Android 常用控件tips

作者: 燊在锦官城 | 来源:发表于2020-08-06 15:31 被阅读0次

    1. 用代码设置ImageView的src和background

    设置ImageView的src:

    setImageDrawable(Drawable drawable);
    setImageBitmap(Bitmap bm);
    setImageResource(int resId);
    
    

    代码设置ImageView的background:

    setBackgroundReource(int resid)
    setBackground(Drawable background)
    setBackgroundColor(int color)
    setBackgroundDrawable(Drawable background) //This method was deprecated in API level 16. use setBackground(Drawable) instead
    
    

    2. 在dimens.xml中保存不带单位的数值

    要在dimens.xml中保存不带单位的数值,可以用如下格式来定义。

    <item name="text_line_spacing" type="dimen" format="float">1.2</item>
    

    在上述定义中,type=”dimen”属性表示定义的item的资源类型是dimen类型。除了可以使用”dimen”外,还可以使用color,string,style等类型,但由于其他类型都可以直接定义,且没有数值的约束,所以一般不需要通过这种方法来定义。format=”float”属性表示定义的数值类型是float类型。除了”float”类型外,还可以使用boolean,fraction,integer等类型。例如:

    <item name="top_weight" type="dimen" format="integer">5</item>
    

    要在xml中引用上述定义的dimens,可以使用@dimen/text_line_spacing。
    要在代码中引用上述定义的dimens,可以使用如下代码。

    TypedValue outValue = new TypedValue();
    getResources().getValue(R.dimen.text_line_spacing, outValue, true);
    float value = outValue.getFloat();
    

    3. 在TextView中android:ellipsize="marquee"确保有效的方法

    • xml设置
                android:singleLine="true"
                android:ellipsize="marquee"
                android:marqueeRepeatLimit="marquee_forever"
    
    • 文字动态设置的话需要超出一行
    • 在当前控件是visible的情况下textView.setSelected(true);

    4. Android自定义Dialog设置有蒙版半透明背景的方法

    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:backgroundDimAmount">0.42</item>
    

    5. ScrollView中嵌套WebView时的焦点问题(ListView的item焦点抢夺同理)

    外层使用ScroolView,内层嵌套使用WebView,每次进入Activity页面时,整个页面起始位置并不是顶部,这是因为WebView加载后获得焦点导致的(ListView也会出现类似问题,即使修正了高度,也会主动获得焦点,使得屏幕产生错误的滚动)
    通过设置ScrollView包含的第一个viewgroup的

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:descendantFocusability="blocksDescendants" >
    

    viewgroup会覆盖子类控件而直接获得焦点来轻松解决问题。

    6. 设置按钮不可点击

    button.setEnabled(false);
    或者
    button.setClickable(false);
    
    • 注意:
      setClickable(false)方法一定要在setOnClickListener()方法之后用;
      因为setOnClickListener()方法会重新绘制View;

    7. 编辑框光标保持光标位于内容最后

    setText之后设置:

    etView.requestFocus();
    

    否则先获得了焦点,后续再设置内容,此时焦点肯定是放在内容之前的了,则就需要额外调用setSelection去调整位置了

    etView.setSelection(etView.getText().toString().length());
    

    8. ImageView扩大点击区域

    ImageView 直接设置其padding值达到目的,或者

    android:scaleType="centerInside"
    android:src="@drawable/ic_edit"
    

    此时可以直接设置控件宽高来控制大小,注意不能用background,这会导致图片变形

    9. 禁止EditText自动获取焦点

    android:focusable="true"   
    android:focusableInTouchMode="true"
    

    设置光标不可见

    cursorVisible
    

    10. TextView的文字也可以设置按下效果

    新建 color/text_color_selector.xml

        <?xml version="1.0" encoding="utf-8"?>
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:color="@color/white" android:state_pressed="true"></item>
            <item android:color="@color/dail_black" android:state_pressed="false"></item>
        </selector>
    

    11. 一个控件设置TextView和两个icon

    <style name= "text_mine_line">
        <item name="android:textSize">14dp</item>
        <item name="android:textColor">@color/color_666666</item>
        <item name="android:paddingStart">18dp</item>
        <item name="android:paddingEnd">18dp</item>
        <item name="android:drawableEnd">@mipmap/ic_more</item>
        <item name="android:gravity">center_verticall</item>
        <item name="android:drawablePadding">14dp</item>
        <item name="android:background">@drawable/shape_line_gray</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">49dp</item>
    </style>
    

    12. 监听ViewFlipper滑动的子View

    public class MyViewFlipper extends ViewFlipper {
        public MyViewFlipper(Context context) {
            super(context);
        }
    
        public MyViewFlipper(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public void showNext() {  //从继承关系中发现当子view变化的时候会调用该方法,因此在这里弄个回调
            super.showNext();
            mOnViewCountListener.viewCount(getDisplayedChild());
        }
       private OnViewCountListener mOnViewCountListener;
        public void setOnViewCountListener(OnViewCountListener mOnViewCountListener)
        {
            this.mOnViewCountListener=mOnViewCountListener;
        }
       public interface OnViewCountListener{
         void viewCount(int count);
    
       }
    }
    

    13. 官方提供的自动改变文本大小的TextView

    在XML中设置

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto" // 加入app命名空间
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_45">
    
        <android.support.v7.widget.AppCompatTextView
            android:layout_width="@dimen/dimen_105"
            android:layout_height="@dimen/dimen_32"
            android:maxLines="1"
            android:textSize="@dimen/dimen_sp_12"
            android:textColor="@color/button_r_b_font_color" 
            app:autoSizeTextType="uniform" // 设置TextView大小设置样式为支持改变(none时为不支持改变)
            app:autoSizeStepGranularity="@dimen/lib_search_dimen_sp_1"   // 每次改变的尺寸阶梯
            app:autoSizeMinTextSize="@dimen/lib_search_dimen_sp_8" 
            app:autoSizeMaxTextSize="@dimen/lib_search_dimen_sp_12" /> 
    
    </RelativeLayout>
    

    在代码中动态设置

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_45">
    
        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/txt_price_section_item"
            android:layout_width="@dimen/dimen_105"
            android:layout_height="@dimen/dimen_32"
            android:background="@drawable/red_black_selector_bg"
            android:maxLines="1"
            android:textSize="@dimen/dimen_sp_12"
            android:textColor="@color/button_r_b_font_color" />
    </RelativeLayout>
    

    在代码中进行改变字号的设置

    TextViewCompat.setAutoSizeTextTypeWithDefaults(
        textView, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM); 
    TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
        textView, 8, 25, 1, TypedValue.COMPLEX_UNIT_SP);
    
    • 控件的宽度和高度必须要有具体的值,不能设置为wrap_content
    • 单行显示需要使用maxLines="1"

    14. 获取控件宽高建议使用的方法

    • 重写Activity的onWindowFocusChanged方法,在该方法中获取
    @Override  
    public void onWindowFocusChanged(boolean hasFocus) {  
        super.onWindowFocusChanged(hasFocus);  
        //此处可以正常获取width、height等  
    } 
    
    • 将一个runnable添加到Layout队列中:View.post()
    view.post(new Runnable() {  
        @Override  
        public void run() {  
            view.getHeight();  
        }  
    });
    

    15. 动态修改TextView的图片

    Drawable drawable=getResources().getDrawable(R.drawable.ic_phone);
    drawable.setBounds(0,0,30,35);//第一0是距左边距离,第二0是距上边距离,30、35分别是长宽
    tv_phone.setCompoundDrawables(drawable,null,null,null);//只放左边
    
    setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom)
    

    如果想手动设置大小的话就要用setCompoundDrawables,事先要给Drawable设置setBounds。
    如果按照原有比例大小显示图片就使用setCompoundDrawablesWithIntrinsicBounds

    16. 在 LinearLayout 添加分割线 divider

    LinearLayout有两个属性

    1、divider

    android:divider = ""
    

    divider可以是图片文件,也可以是xml绘制的shape。
    使用shape的时候一定要添加<size> ,一定要添加color,即使是透明也要写上

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="@color/black" />
        <size android:height="1px" android:width="1px" />
    </shape>
    

    2、showDividers

    android:showDividers = "middle|end|beginning|none"
    
    • middle 在每一项中间添加分割线
    • end 在整体的最后一项添加分割线
    • beginning 在整体的最上方添加分割线
    • none 无
    1. dividerPadding 设置间隔

    17. clipToPadding

    场景:常常用于paddingTop,假设内部有个属性设置了paddingTop,但是滑动的时候paddingTop的空间无法一起滑动则使用该属性
    如设置

    Android:clipToPadding=false
    

    可以使列表的paddingTop跟随着一起滑动。

    18. 编辑框切换设置不可编辑和可编辑

        /**
         * 设置编辑框不可编辑
         * @param editText
         */
        public static void setEditTextNotEdit(EditText editText){
            editText.setCursorVisible(false);
            editText.setFocusable(false);
            editText.setFocusableInTouchMode(false);
        }
    
        /**
         * 编辑框获取焦点
         * @param editText
         */
        public static void getEditFocus(EditText editText) {
            editText.setFocusable(true);
            editText.setFocusableInTouchMode(true);
            editText.setCursorVisible(true);
            editText.requestFocus();
            editText.requestFocusFromTouch();
            editText.setSelection(editText.getText().toString().length());
        }
    

    19. 使RecyclerView 的当前Item居中显示

    LinearSnapHelper & PagerSnapHelper

    Google 内置了两个默认实现类,LinearSnapHelper和PagerSnapHelper。

    • LinearSnapHelper: 可以使RecyclerView 的当前Item 居中显示(横向和竖向都支持)
    • PagerSnapHelper: 使RecyclerView像ViewPager一样的效果,每次只能滑动一页(LinearSnapHelper支持快速滑动), PagerSnapHelper也是Item居中对齐。

    20. Webview支持缩放并隐藏控制条

            webSettings.setSupportZoom(true); //支持缩放
            webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。
            webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件`
    

    此外检查wap页面的源代码

            <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"/>
    

    如果user-scalable=no,或者initial-scale和maximum-scale,minimum-scale相等,是无法缩放的。

    webView设置背景图片,如果直接给webView设置android:background是无效的,必须在Java代码中

    webView.setBackgroundColor(0);
    

    21. EditText可以弹出安全键盘的方法

    editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
    
    if (isShowPwd) {
        // 显示密码
        etPwd.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); 
    }else{
        // 隐藏密码
        etPwd.setTransformationMethod(PasswordTransformationMethod.getInstance());
    }
    

    22. 列表中Glide加载图片大小显示不正常

    android:adjustViewBounds="true"
    

    adjustViewBounds只有在ImageView一边固定,一边为wrap_content的时候才有意义。设置为true的时候,可以让ImageView的比例和原始图片一样,以达到让图片充满的ImageView的效果。

    23. 处理返回时关闭输入法的同时关闭dialog

    重写EditText的onKeyPreIme方法,并设置回调来更新程序的UI

        @Override
        public boolean onKeyPreIme方法,并设置回调来更新程序的UI(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (listener != null) {
                    listener.back(this);
                }
            }
            return false;
        }
    

    24. 代码中动态添加radiobutton的间隔设置

    设置间隔需要把setLayoutParams()放到addView之后,才有效果

    RadioGroup.LayoutParams bt_params = new RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ScreenUtil.dp2px(50,this));
    bt_params.setMargins(0,ScreenUtil.dp2px(10,this),0,0);
    radioGroup.addView(radioButton);
    radioButton.setLayoutParams(bt_params);
    

    25. 点击ViewGroup时其子控件也变成pressed状态

    让某个view自己能处理touch事件,也即设置clickable、longClickable为true;

    26. 设置编辑框弹出输入法的一种办法

            private EditText searchEdit;
            searchEdit.setCursorVisible(false);
            searchEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if(hasFocus){               
                        searchEdit.setCursorVisible(true);//点击后显示光标,弹出输入法
                    }
                }
            });
    

    在他的父级设置

    android:focusableInTouchMode="true"
    android:focusable="true"
    

    27. 获取LinearLayout的宽度和高度

    在调用这两个方法之前,必须调用View.measure方法先测量组件宽度和高度

    linearlayout.measure(0,0);  
    //获取组件宽度  
    int width = linearlayout.getMeasuredWidth();  
    //获取组件高度  
    int height = linearlayout.getMeasuredHeight();  
    

    28. NestedScrollView嵌套滑动RecycleView

    mRecycleView.setNestedScrollingEnable(false);
    

    29. AppCompat 主题中 Button 的默认 style 导致的图片变形问题

    默认 style 是"Base.Widget.AppCompat.Button"有最小宽高,具体属性参数如下:

     <style name="Base.Widget.AppCompat.Button" parent="android:Widget">
            <item name="android:background">@drawable/abc_btn_default_mtrl_shape</item>
            <item name="android:textAppearance">?android:attr/textAppearanceButton</item>
            <item name="android:minHeight">48dip</item>
            <item name="android:minWidth">88dip</item>
            <item name="android:focusable">true</item>
            <item name="android:clickable">true</item>
            <item name="android:gravity">center_vertical|center_horizontal</item>
     </style>
    

    解决方案

     <style name="MyButton_Style" parent="Base.Widget.AppCompat.Button">
            <item name="android:minHeight">0dip</item>
            <item name="android:minWidth">0dip</item>
        </style>
    

    在values/styles.xml文件的AppTheme style节点中添加如下代码:

    <item name="android:buttonStyle">@style/MyButton_Style</item>
    

    30. RadioGroup调用check(int)方法时,onCheckedChanged方法被执行两次

    改为直接根据id获取子RadioButton对象来setChecked()

    ((RadioButton)mListenKindGroup.findViewById(R.id.listen_kind_group)).setChecked(true);
    

    31. ImageView setAlpha(float)、setAlpha(int)及setImageAlpha(int)的区别

    • setAlpha(float)推荐使用,取值范围为0.0f-1.0f,透明到不透明
    • setAlpha(int),已废弃,不推荐使用,取值范围为1-255,表示透明到不透明
    • setImageAlpha(int),取值范围1-255,表示透明到不透明

    32. RelativeLayout的circular dependency问题

    如果 RelativeLayout 的 height 是 wrap_content,而且它的子控件是 ALIGN_PARENT_BOTTOM,就会产生 circular dependency,导致布局铺满全屏。

    • 解决方案:1. 动态设置布局高度 2. 替换成 LinearLayout 或其他布局。

    33. EditText禁止回车键换行

    android:inputType="text"
    

    相关文章

      网友评论

        本文标题:Android 常用控件tips

        本文链接:https://www.haomeiwen.com/subject/wzazrktx.html