7-25工作日记,关于布局所不知的几点细节

本文档详细介绍了Android开发中常见的技术细节,包括XML命名空间的作用、资源ID获取方法、控件焦点管理、字体适配方案、横竖屏设置及Activity状态保存等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

一、关于XML中xmlns:android="http://schemas.android.com/apk/res/android"的意思

二、使用getIdentifier()方法根据资源名来获取其ID

三、XML中标签的相关属性android-focusable,EditText不自动获取焦点;单行显示;光标颜色;android:scaleType属性

四、GradientDrawable,类似的还有ShapeDrawable

五、进度条相关属性设置ProgressBar

六、控件的setFocusable和requestFocus的区别

七、APP字体的设置以适配不同手机屏幕

八、Android的横竖屏设置

九、保存Activity实例状态的方法:onSaveInstanceState()

十、隐藏标题栏,设置Window.FEATURE_NO_TITLE无效的解决方法

十一、KeyEvent event.getRepeatCount

目录

 

一、关于XML中xmlns:android="http://schemas.android.com/apk/res/android"的意思

二、使用getIdentifier()方法根据资源名来获取其ID

三、XML中标签的相关属性android-focusable,EditText不自动获取焦点;单行显示;光标颜色;android:scaleType属性

四、GradientDrawable,类似的还有ShapeDrawable

五、进度条相关属性设置ProgressBar

六、控件的setFocusable和requestFocus的区别

七、APP字体的设置以适配不同手机屏幕

八、Android的横竖屏设置

九、保存Activity实例状态的方法:onSaveInstanceState()

十、隐藏标题栏,设置Window.FEATURE_NO_TITLE无效的解决方法

十一、KeyEvent event.getRepeatCount

十二、Dialog的setCancelable和setCanceledOnTouchOutside

十三、在布局文件设置:descendantFocusability


 


 

 


一、关于XML中xmlns:android="http://schemas.android.com/apk/res/android"的意思

参考文献:https://blog.youkuaiyun.com/zhangxichao100/article/details/51868986

<LinearLayout
    android:id="@+id/sso_login_root"
    xmlns:PasswordEditText="http://schemas.android.com/apk/res-auto"
    xmlns:SsoCircleButton="http://schemas.android.com/apk/res-auto"
    xmlns:SsoClearEditText="http://schemas.android.com/apk/res-auto"
    xmlns:TitleBar="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/sso_color_bg"
    android:orientation="vertical">
</LinearLayout>

xmlns是XML Namespaces的缩写,指XML的命名空间。schemas是XML文档的一种约束文件形式。

使用规则:首先定义命名空间xmlns:namespace-prefix="namespaceURI"。Android中xml中的使用是:xmlns:前缀=http://schemas.android.com/apk/res/应用程序包路径;

按格式:namespace-prefix(前缀):属性
      如果使用xmlns,则xmlns的定义必须放在最外层开始的的标记中。
      当命名空间被定义之后,所有带有相同前缀的子元素都会与同一个命名空间相关联。避免XML解析器对xml解析时的发送名字冲突,这就是使用xmlns的必要性。当自定义的View有自己的属性的时候,就用到xmlns来定义一个命名空间。


二、使用getIdentifier()方法根据资源名来获取其ID

/**
     * 返回组件资源ID
     *
     * @param paramContext
     * @param paramString
     * @return
     */
    public static int getId(Context paramContext, String paramString) {
        return paramContext.getResources().getIdentifier(paramString, "id", paramContext.getPackageName());
    }

//调用封装的代码
        mTitleBar = (TitleBar) findViewById(ResourceUtil.getId(this, "sso_login_title_bar"));

//XML文件中的控件
<com.sdk.view.TitleBar
        android:id="@+id/sso_login_title_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        TitleBar:sso_title_text="@string/str_login"/>

源码

/**
     * Return a resource identifier for the given resource name.  A fully
     * qualified resource name is of the form "package:type/entry".  The first
     * two components (package and type) are optional if defType and
     * defPackage, respectively, are specified here.
     * 
     * <p>Note: use of this function is discouraged.  It is much more
     * efficient to retrieve resources by identifier than by name.
     * 
     * @param name The name of the desired resource.
     * @param defType Optional default resource type to find, if "type/" is
     *                not included in the name.  Can be null to require an
     *                explicit type.
     * @param defPackage Optional default package to find, if "package:" is
     *                   not included in the name.  Can be null to require an
     *                   explicit package.
     * 
     * @return int The associated resource identifier.  Returns 0 if no such
     *         resource was found.  (0 is not a valid resource ID.)
     */
    public int getIdentifier(String name, String defType, String defPackage) {
        if (name == null) {
            throw new NullPointerException("name is null");
        }
        try {
            return Integer.parseInt(name);
        } catch (Exception e) {
            // Ignore
        }
        return mAssets.getResourceIdentifier(name, defType, defPackage);
    }

三、XML中标签的相关属性android-focusable,EditText不自动获取焦点;单行显示;光标颜色;android:scaleType属性

参考文献:https://blog.youkuaiyun.com/small5e4444/article/details/47399591

                  https://my.oschina.net/u/141132/blog/380740

                  https://www.cnblogs.com/nimorl/p/8081542.html

<RelativeLayout
        android:id="@+id/sso_login_username_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/dimen_16dp"
        android:layout_marginRight="@dimen/dimen_16dp"
        android:focusable="true"
        android:focusableInTouchMode="true">

        <com.sdk.view.CEditText
            android:id="@+id/sso_login_username_edt"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dimen_50dp"
            android:hint="@string/str_login_username_edit_hint"
            android:gravity="center_vertical"
            android:maxLength="50"
            android:singleLine="true"
            android:textCursorDrawable="@drawable/sso_shape_cursor"
            android:textSize="@dimen/dimen_16sp"
            SsoClearEditText:sso_show_userIcon="false"
            SsoClearEditText:sso_login_page="true"
            SsoClearEditText:sso_underlineColor="@color/sso_color_maintheme" />


        <ImageView

            android:id="@+id/sso_login_username_imgR"
            android:layout_width="@dimen/dimen_44dp"
            android:layout_height="@dimen/dimen_44dp"
            android:scaleType="center"
            android:layout_alignParentRight="true"
            android:layout_alignRight="@+id/sso_login_username_edt"
            android:layout_centerVertical="true"
            android:src="@drawable/sso_down"/>

    </RelativeLayout>

因为EditText默认会自动获取焦点,取消这个默认行为的方式就是在EditText的父级控件中设置两个属性:

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

显示单行的属性设置:android:singleLine="true"

控制光标颜色的属性设置:android:textCursorDrawable="@drawable/sso_shape_cursor"   其文件内容为:

<!--sso_shape_cursor.xml-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/main_theme_color" />

    <size
        android:width="2dp"
        android:height="@dimen/dimen_14dp"/>

    <corners
        android:radius="@dimen/dimen_1dp">
    </corners>

</shape>

控制图片缩放的属性设置:android:scaleType="center"   其值有多种,截参考文献第三篇的内容如图:


四、GradientDrawable,类似的还有ShapeDrawable

参考文献:https://www.cnblogs.com/popfisher/p/5606690.html

<?xml version="1.0" encoding="utf-8"?>

 <!-- 
    android:shape=["rectangle" | "oval" | "line" | "ring"]
    shape的形状,默认为矩形,可以设置为矩形(rectangle)、椭圆形(oval)、线(line)、环形(ring)

    下面的属性只有在android:shape="ring时可用:
    android:innerRadius           内环的半径。
    android:innerRadiusRatio    浮点型,以环的宽度比率来表示内环的半径,
    例如,如果android:innerRadiusRatio,表示内环半径等于环的宽度除以5,这个值是可以被覆盖的,默认为9.

    android:thickness              环的厚度
    android:thicknessRatio      浮点型,以环的宽度比率来表示环的厚度,例如,如果android:thicknessRatio="2",
    那么环的厚度就等于环的宽度除以2。这个值是可以被android:thickness覆盖的,默认值是3.
    
    android:useLevel            boolean值,如果当做是LevelListDrawable使用时值为true,否则为false.
  -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle" >
    <!--宽度和高度 
        android:width   整型 宽度
        android:height  整型 高度
    -->
    <size
        android:width="50dp"
        android:height="50dp"/>

    <!--圆角
        android:radius                    整型 半径
        android:topLeftRadius           整型 左上角半径
        android:topRightRadius               整型 右上角半径
        android:bottomLeftRadius           整型 左下角半径
        android:bottomRightRadius         整型 右下角半径
    -->
    <corners
        android:radius="10dp"/><!-- 设置圆角半径,可以分别设置4个角 -->
    
    <!--渐变,这个设置之后一般就不要设置solid填充色了
        android:startColor  颜色值     起始颜色
        android:endColor    颜色值     结束颜色
        android:centerColor 整型       渐变中间颜色,即开始颜色与结束颜色之间的颜色
        android:angle       整型       
     渐变角度(PS:当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上。angle必须为45的整数倍)

        android:type        ["linear" | "radial" | "sweep"] 渐变类型(取值:linear、radial、sweep)
                            linear 线性渐变,这是默认设置
                            radial 放射性渐变,以开始色为中心。
                            sweep 扫描线式的渐变。

        android:useLevel     ["true" | "false"]              
     如果要使用LevelListDrawable对象,就要设置为true。设置为true无渐变。false有渐变色

        android:gradientRadius 整型   
        渐变色半径.当 android:type="radial" 时才使用。单独使用 android:type="radial"会报错。

        android:centerX      整型     渐变中心X点坐标的相对位置
        android:centerY      整型     渐变中心Y点坐标的相对位置
    -->
    <gradient
        android:startColor="@android:color/white"
        android:centerColor="@android:color/black"
        android:endColor="@android:color/black"
        android:useLevel="true"
        android:angle="45"
        android:type="radial"
        android:centerX="0"
        android:centerY="0"
        android:gradientRadius="90"/>
    
    <!-- 间隔
        内边距,即内容与边的距离 
        android:left        整型 左内边距
        android:top        整型 上内边距
        android:right      整型 右内边距
        android:bottom   整型 下内边距
    -->
    <padding
        android:left="5dp"
        android:top="5dp"
        android:right="5dp"
        android:bottom="5dp"/>
    
    <!--填充 
        android:color   颜色值 填充颜色
    -->
    <solid
        android:color="@android:color/white"/><!-- 填充的颜色 -->
    
    <!--描边 
        android:width          整型      描边的宽度
        android:color           颜色值    描边的颜色
        android:dashWidth   整型      表示描边的样式是虚线的宽度, 值为0时,表示为实线。值大于0则为虚线。
        android:dashGap     整型      表示描边为虚线时,虚线之间的间隔 即“ - - - - ”
    -->
    <stroke
        android:width="1dp" <!-- 边框宽度 -->
        android:color="@android:color/black"
        android:dashWidth="1dp"
        android:dashGap="2dp"/>
    
</shape>

上面的代码是引用自参考文献,做GradientDrawable的一种实现方式——通过静态的xml文件;同样还可以使用java代码动态实现。

         // 创建状态管理器
        StateListDrawable drawable = new StateListDrawable();
        GradientDrawable normalDrawable = new GradientDrawable();
        normalDrawable.setColor(mBgNormalColor);
        normalDrawable.setStroke(ResUtil.dp2px(getContext(), 1f), mBgNormalStrokeColor);
        normalDrawable.setCornerRadius(ResUtil.dp2px(getContext(), mRadius));
        drawable.addState(mNormalState, normalDrawable);

        setBackgroundDrawable(drawable);//将修改完的layerDrawable设为背景

其get()、set()方法都是相通的,与xml类似。


五、进度条相关属性设置ProgressBar

参考文献:https://blog.youkuaiyun.com/wenwen091100304/article/details/53428249

                  https://blog.youkuaiyun.com/u013403478/article/details/22602883

<ProgressBar
            android:id="@+id/sso_pb_login"
            android:layout_width="@dimen/dimen_14dp"
            android:layout_height="@dimen/dimen_14dp"
            android:layout_gravity="right|center_vertical"
            android:layout_marginRight="@dimen/dimen_20dp"
            android:indeterminate="true"
            android:indeterminateDrawable="@drawable/sso_anim_progressbar"
            android:indeterminateDuration="1500"
            android:visibility="gone"/>

其中sso_anim_progressbar文件的内容如下:

<?xml version="1.0" encoding="utf-8"?>
 <rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"            #初始角度
    android:toDegrees="540"            #结束时角度,值为正时顺时针旋转,值为负时逆时针旋转
    android:pivotX="50%"               #旋转中心x轴坐标,取值可以是数值(50)、百分数(50%)、百
                                        分数p(50%p),当取值为数值时,缩放起点为View左上角坐标
                                        加具体数值像素,当取值为百分数时,表示在当前View左上角坐
                                        加上View宽度的具体百分比,当取值为百分数p时,表示在View
                                        左上角坐标加上父控件宽度的具体百分比
    android:pivotY="50%"               #同上

    android:duration="700"             #动画持续时间,毫秒为单位
    android:fillAfter="true"           #动画结束后,保持结束时的状态
    android:fillBefore="true"          #动画结束后,恢复为初始状态
    android:fillEnabled="true"         #效果同上
    android:repeatCount="5"            #重复次数,取值为-1时无限重复,默认动画执行一次
    android:repeatMode ="reverse"      #重复模式,有reverse和restart两个值,前者为倒序回放,后者为重新开始
    android:interpolator="@android:anim/accelerate_decelerate_interpolator" #插值器,后面单独讲             
    />

实际进度与ProgressBar行为分别设置:android:indeterminate="true"

设置为True后,进度条不明显显示进度。即:按照事先设定好的(如持续时间+次数等)进行显示,与实际百分比不对应。


六、控件的setFocusable和requestFocus的区别

setFocusable是将控件设置成可获取焦点状态,默认是无法获取焦点的,只有设置成true,才能获取控件的点击事件;
requestFocus是设置是否获得焦点。若有requestFocus()被调用时,后者优先处理。注意在表单中想设置某一个如EditText获取焦点,光设置这个是不行的,需要将这个EditText前面的focusable都设置为false才行。在Touch模式下获取焦点需要设置focusableInTouchMode为true。
  简单来说:
  setFocusable是设为可以获取焦点。
  requestFocus是设置要获取焦点。


七、APP字体的设置以适配不同手机屏幕

参考文献:https://blog.youkuaiyun.com/qq_32521313/article/details/52936674

在界面的Activity中重写getResources()方法。通常这个Activity可以是根或是主;代码如下:

    @Override  
    public Resources getResources() {  
        Resources res = super.getResources();  
        Configuration config=new Configuration();  
        config.setToDefaults();  
        res.updateConfiguration(config,res.getDisplayMetrics());  
        return res;  
    }  

注:getResources()方法是全局的,由于重写了getResources()方法,导致APP全局将不再受到用户调整系统字体大小的影响。

 


八、Android的横竖屏设置

参考文献:https://www.cnblogs.com/bluestorm/archive/2012/05/07/2486954.html

横竖屏切换后Activity会重新执行onCreate()函数,在Mainfest.xml文件加入下面设置,就不会调onCreate函数,而是调onConfigurationChanged().这样就可以控制横竖屏切换了。


android:screenOrientation="user"
android:configChanges="orientation|keyboardHidden"

<!--一直保持横屏-->
android:screenOrientation="landscape"
//等效代码:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

<!--一直保持竖屏-->
android:screenOrientation="portrait"
//等效代码:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

启动的时候是横屏的话就横屏表示,纵屏的话就纵屏表示,手机切换横竖屏不能用。实现过程如下

1、添加XML设置

<!--Mainfest.xml-->
android:screenOrientation="sensor"
android:configChanges="orientation|keyboardHidden"

2、取屏幕长宽对比

Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
if (width > height) {
    orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else {
    orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}

3、调用this.setRequestedOrientation(mOrientation)

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    this.setRequestedOrientation(mOrientation);
}

 


九、保存Activity实例状态的方法:onSaveInstanceState()

参考文献:https://www.cnblogs.com/fuyangyang/p/5483329.html

当系统内存不足时,不在栈顶的Activity可能被回收,此时需要保存一些数据,可以理解为网上上填表格的情景,当然希望之前填的数据存在,而不需要再重新填一次。

此时就适合用onSaveInstanceState()。该回调方法会保证一定在Activity被回收之前调用,其保存数据的方式是借助Bundle。如Activity的onCreate()方法的参数。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null) {
            String oldString = savedInstanceState.getString("Activity");
        }
        
    }

重写onSaveInstanceState(),代码如下:


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
        String string = "activity 被系统回收了怎么办?";
        outState.putString("Activity", string);
    }

 

 


十、隐藏标题栏,设置Window.FEATURE_NO_TITLE无效的解决方法

参考文献:https://blog.youkuaiyun.com/bingjianIT/article/details/51706518

隐藏标题栏方式:

requestWindowFeature(Window.FEATURE_NO_TITLE);

无效的原因可能是Activity继承自AppCompatActivity。将父类改为Activity。

或者:在OnCreate() 方法中添加如下代码:

if (getSupportActionBar() != null){
   getSupportActionBar().hide();
}

十一、KeyEvent event.getRepeatCount

参考文献:https://blog.youkuaiyun.com/ProgramResearch/article/details/69486049


十二、Dialog的setCancelable和setCanceledOnTouchOutside

参考文献:https://blog.youkuaiyun.com/u012255016/article/details/49888881

dialog.setCancelable(false);

dialog弹出后会点击屏幕或物理返回键,dialog不消失

dialog.setCanceledOnTouchOutside(false);

dialog弹出后会点击屏幕,dialog不消失;点击物理返回键dialog消失


十三、在布局文件设置:descendantFocusability

参考文献:https://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants"
    android:background="@android:color/transparent">

该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。

属性的值有三种:

        beforeDescendants:viewgroup会优先其子类控件而获取到焦点

        afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

        blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值