杂乱无章--Android项目开发完成用到的知识点(一)

杂乱无章(一)

  1. TabLayout设置其下划线的宽度,有一种方法是通过放射来设置的,在api28中,把mTabStrip改名为SlidingTabIndicator。mTextView改名为textView(自定义TabLayout里的字体)。
  2. 动态设置RecyclerView某一个或某一组或所有Item的margin,这是需要用到ItemDecoration。
  3. 我们先假设一个场景,一段文本绘制在一张图片上面。一般来说在Android布局文件xml中通过FameLayout作为ViewGroup,在其中先放入一个ImageView,然后再放入一个TextView,这样TextView就绘制在了图片上面。不过我们还可以把图片当作是背景来设如TextView的background属性,通过TextView的padding属性来控制文字与图片的相对位置。这时的效果与用FameLayout包着实现一致,并且可以节省绘制布局是的性能开销。
  4. ListView中给Item设置分割先可以在静态中设置:android:divider="颜色" android:dividerHeight="高度"虽然也可以动态设置,不过动态设置的话会产生一些小问题。
  5. 关于Android string.xml的占位符:%d可替换为数字,%s可替换为字符串;如何把0.00000赋值给某string变成0.0?–>占位符用%1$.1f;如果把1.132赋值给某string变成1?–>占位符用%1$.0f。大概的意思为:前者保留前面一位与小数点后一位,后者保留前面一位与小数点后0位。
  6. 在布局中,我们想不显示某张图片的右边一截,我们可以通过android:marginEnd="-多少dp"来处理。
  7. 禁止EditText换行:android:singlelines="true"这样键盘的“回车”键就会变成“下一项”键。
  8. 关于缩放,无论缩多小,真实的大小不变。
  9. 假如有两个控件:layout_width:"match_parent&&layout_heigth="wrap_content"控件A;layout_width:"match_parent&&layout_heigth="wrap_content"控件B,ViewGroup假如是LinerLayout 且B在A的下面。我们可以先让它们稍微重叠在一起。那么显示的布局在默认情况为B叠在A的上面。如果我们需要的是A叠在B上面的这中情况呢?那么可以通过b.setTranslateZ(-1) 或者 a.setTranslateZ(1)来实现。
  10. 申请权限后等待操作回调的 onRequestPermission方法最好放在Activity中。
  11. 一般来讲,我们做缩放动画缩小一张布局中图片,它是上下左右一块缩小的,这样图片在布局中的位置与大小都发生变化。假如我们需要图片缩小了但图片的底部位置依旧,那么可以在RelativeLayout中,我们对将要缩小的图片设置android:alignParentBottom="true" android:marginBottom=“xxdp”这样无论图片怎么缩放,最底部的位置都不变。
  12. 假如对一个控件设置它对y轴的位移动画,那么在属性动画中valueAnimation.ofInt(x,y)提前设好其中的x,就等于在初始的时候已经translateY了x的距离。
  13. viewGroup被View.GONE了,那么此时获取不到它的高度。要在View.INVISIBLE?或View.VISIBLE后才能getHeight
  14. 动画导致APP crash,可能是因为在从做动画的页面切换到另一张页面时,没有对动画进行cancel
  15. PopupWindow设置动画要在style.xml里写好
<style name="popup_select_text_size_animation" parent="android:Animation">

        <item name="android:windowEnterAnimation">@anim/入场动画
        </item><!--- 进入动画-->
        <item name="android:windowExitAnimation">@anim/出场动画</item>
 </style>
  1. viewpager.setOffScreenPageLimit(int)为viewpage预加载页面,不过在viewpager的源码中已经默认了无论怎样都会帮你预加载一张页面。
  2. 有时候setTextColor(Color)设不进去可能是因为setTextColor(Color)要变成setTextColor(getResource.getColor(xxx))
  3. TextView.setText()里面一定是string,不是的话回报错。
  4. 使用标签来实现按钮点击,在写其xml的时候,state_pressed要在state_enable上面。
  5. 使用ripple效果,要在你想实现的控件中把写好标签的xml,设入android:background="xxx"中,设入哪个控件,哪个控件就有ripple点击效果。
  6. 用ScrollView包ConstrainLayout:包不主的话ScrollView要设置android:fillviewport="true,效果相当于android:layout_height="match_parent
  7. 要想从一开始就获取RecyclerView中item的高度,可以如下获取:
 RecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                recyclerViewHeight = RecyclerView.getHeight();//获取RecyclerView高度
                recyclerViewTop = RecyclerView.getTop();//获取RecyclerView的top坐标
                recyclerViewBottom = RecyclerView.getBottom();//获取RecyclerView的bottom坐标
                for (int i = 0; i < RecyclerView.getChildCount(); i++) {
                        View view = layoutManager.findViewByPosition(i);
                        if (view != null) {
                           //处理获取到的item
                        }
                    }
                }
            }
        });

getViewTreeObserver().addOnGlobalLayoutListener会回调多次,可以在获取到你想要的值的时候通过RecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);把它移除监听。

  1. 关于longitude与latitude:经度longitude越小则越往左,纬度latitude越小则越往下。
  2. Android中集成的百度地图在不用开启gps的情况下也能实现定位功能。(因为除了gps定位之外,还可以通过基站定位。如周围到处都是用于手机通讯的基站,软件可以知道信号是通过周围哪个基站传递的,自然就可以获取到大致的位置)
  3. Butterknife的绑定要在view操作之前完成。
  4. JsonObject.optString(xxx)会在得不到值的时候返回一个“”字符串。
  5. Json.has(xxx)是判断一个Json中是否含有某个key值。
  6. PopupWindow是阻塞线程的,PoupupWindow弹出时程序会等待。在非主线程中直接new Handle()会报Can’t create handle inside thread has got called Lopper.prepare()异常。需要先调用Loop.pare()启用Lopper,然后调用Looper.loop()让Looper开始工作。
  7. 怎么在setOnTouchListener()中去掉需要复写performOnClick的警告。a.在被监听的控件中重写performClick方法;b.在onTouch中写入view.performClick()就能去掉烦人的黄色警告。
//自定义EditText控件中
 @Override
    public boolean performClick() {
        return super.performClick();
    }
//使用时:
EditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    EditText.performClick();
                }
                return false;
            }
        });
  1. 关于Multidex:Android系统中有个bug,即只有一个dex。使得dex方法数量被限制在65535之内。我们可以使用implementation 'com.android.support:multidex:1.0.3'这个库,然后在application文件中重写attachBaseContext方法。这样App不仅再有一个dex文件,可能会产生多个dex文件,这样就可以避免64k问题。
 @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
  1. 给DatePicker设置最大值,例如需要弹出一个datePicker的Dialog给用户选择自己的生日日期,当然它最大值肯定是今天。我们可以如下写一个方法:
private void showDatePicker() {
        Calendar calendar = Calendar.getInstance();
        DatePickerDialog datePickerDialog = new DatePickerDialog(context, R.style.主题, new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int year, int month, int dayOfMonth) {
				//获取年月日,月份记得要+1
            }
        }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
        //设置最大值为今天
        datePickerDialog.getDatePicker().setMaxDate(new Date().getTime());
        datePickerDialog.show();
    }
  1. 防止图片变形:假如用ImageView通过android:src="xxx来显示一张图片,并把ImageView的宽设为android:layout_widt="match_parent这样图片会在宽度进行一定的拉伸导致变形,那么可以再增加一个属性:android:adjustnewbound="true"来防止变形。该属性的大概意思是,宽或高其中一方被拉伸,那么另一方也拉伸调整。
  2. JsonObject转JsonArray,JsonArray.put(JsonObject);搞掂。
  3. TextView能否被点击用enable控制。
  4. 用int类型表示一个数就算是355.999999也是355。
  5. 空格也算一个字符,在substring的时候要注意。
  6. ScrollView(嵌着ListView)其初始位置不是在最顶(主要是由于焦点问题)那么时嵌着的ListView.setFocusable(false)就能解决该问题。
  7. sqlit中条件语句 or(或),<>(不等于)。
  8. Activity启动自己,要先finish()然后在new Intent()接着在startActivity;
  9. 数组如果没有初始化则等于null。
  10. EventBus @Subscribe方法要用public。
  11. 刷新LIstView中item的内容,可以在Adapter中暴露一个方法,在Fragment或Activity中实现这个方法,然后Adapter.notifyDataChange刷新。
  12. 自定义zxing的界面,需要在自定义的layout中有一个与一个继承了ViewFinderView的自定义View,并且它们两个的id一定要与官方的id一样并且不能少。id:zxing_barcode_surface,zxing_viewfinder_view。
  13. 在一行中有文本1与文本2,如果文本1无限长的话,文本2就看不见了。那么我们想可以在文本1无限长的情况下,还能看到文本2的所有文本。可以使用作为ViewGroup,再TableLayout中设置 shrinkColunms=0意思是收缩第一列。接着在该ViewGroup里包着,里面放入文本1与文本2就能实现上述需求。
  14. TextView中的android:autoLink指定格式的文本转换为可点击的超链接。但只能控制标准的文本。
  15. DecimalFormat format = new DecimalFormat("$###,###,###.00");->1234.99主要是.00才能格式化出小数点。
  16. sqlite查询不为空:text!="",查询等于某字符串text!=“null”。
  17. Glide调整图片质量,format(PREFER_ARGB_8888)
  18. SpannableStringBuilder可以拼接富文本字符串。
  19. 禁止在EditText中输入表情:
private void init() {
        setFilters(new InputFilter[]{new EmojiExcludeFilter()});
    }
    private class EmojiExcludeFilter implements InputFilter {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            for (int i = start; i < end; i++) {
                int type = Character.getType(source.charAt(i));
                if (type == Character.SURROGATE || type == Character.OTHER_SYMBOL) {//关键
                    return "";
                }
            }
            return null;
        }
    }
  1. 在xml中创建的WebView无法销毁,动态创建的WebView可以销毁;WebView中的字体大小默认为16px;防止中文乱码,加载数据的时候用webview.loadDataWithBaseURL(null,data,"text/html","utf-8",null)
  2. 在TabLayout中有A B C三个Tab,每个对应着A B C三个Fragment,当点击Tab为C的时候,C中Fragment的onCreateView会比viewpage.setOnPageChangeListener要快,可能是setOnPageChangeListener是在页面改变后才回调好。
  3. 点击drawerLayout不穿透底部可在drawerLayout中包着的那个ViewGroup设置clickable="true"或者监听drawerLayout在onDrawerOpened中setClickable(true)
  4. 这个权限会报警不过可以用,可以通过ignore去掉这个警报。报警呢主要是因为该权限是用来改变系统设置的,一般只归系统APP所有。
  5. 格式化号码PhoneNumberUtils.formatNumber(区号+号码,ISO)这样才有效,假如你有个香港号码,要格式话它,不过如果它不是一个标准的香港号码则格式话无效。
  6. substring(2)意思是截取从第二个字符开始到最后一个。
  7. 接收到推送应该怎么跳转到某fragment?在跳转前设置putExtra("xxx"),然后在指定的Activity中的onNewIntext()和onCreate中获取该Extra,并判断将要跳转到那张fragemnt。
  8. notification中的setTimeAfter(xxx)意思是多少秒后把通知从后台直接消失。
  9. 关于自定义view,我们应该怎么在代码中拿出xml里面的宽与高呢?就是在代码中使用:
		final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        int width = getWidth() - paddingLeft - paddingRight;
        int height = getHeight() - paddingTop - paddingBottom;
		//例如我们画一个圆
		canvas.drawCircle(paddingLeft + width/2, paddingTop + height / 2, radius, paint);

在上面的代码中画圆的时候加上了paddingLeft与paddingTop,这是为了时在xml中加入的padding能够作用到我们画的这个图形上,如果我们在画圆时不加上padding,但在出来的效果中padding时有的,只是没有作用到我们画的圆上面。现在还要处理wrap_content,因为源码中如果不指定wrap_content的大小,其作用与match_parent的大小是一样的:

		int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
		// 宽高指定为200
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, 200);
        } else if (widthMeasureSpec == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, heightSpecSize);
        } else if (heightMeasureSpec == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, 200);
        }

给wrap_content的默认大小为200,这时在看回padding,上面说的在画圆的时候加上padding让padding能作用到圆上面,但它的作用会把圆挤小。不过我们在维持圆的大小的同时又有padding,那么可以这么做:

  int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200 + paddingLeft + paddingRight,
                    200 + paddingTop + paddingBottom);
        } else if (widthMeasureSpec == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, heightSpecSize + paddingLeft + paddingRight);
        } else if (heightMeasureSpec == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, 200 + paddingTop + paddingBottom);
        }

这样就能保持圆的大小不变而且也有padding

你可能感兴趣的:(android)