目录
一、关于XML中xmlns:android="http://schemas.android.com/apk/res/android"的意思
二、使用getIdentifier()方法根据资源名来获取其ID
三、XML中标签的相关属性android-focusable,EditText不自动获取焦点;单行显示;光标颜色;android:scaleType属性
四、GradientDrawable,类似的还有ShapeDrawable
六、控件的setFocusable和requestFocus的区别
九、保存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
六、控件的setFocusable和requestFocus的区别
九、保存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会覆盖子类控件而直接获得焦点