liujiangchuan / liujiangchuan/BlogAndroidCN

菜鸟起飞之路-Android开发总结(续)(博客搬家)

Open
#4 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
1
Forks
0
PR merge metrics
No merged PRs in 30d

Description

### 以下内容本人于2016/09/20 22:51在“OhwYaa|东软知识社区”平台首发,现整理到个人博客中。原址仅内部公开:https://www.ohwyaa.com/neusoft.com/blog/66e10dc0-415e-4048-b834-0a85c33a2cb2/view/text

接着上一篇文章,这篇还是以总结为主的技术贴,仍然是先上正文再闲聊。有不对的地方,还请批评指正。

### 1.编程基础
**1.1 Android中的使用**
在AndroidManifest.xml中,元素可以作为子元素,被包含在、、和元素中,但不同的父元素,在应用时读取的方法也不同。

1)在Activity的应用。
xml代码段:
```




```
java代码段:
```
ActivityInfo info=this.getPackageManager() .getActivityInfo( getComponentName(), PackageManager.GET_META_DATA);
String msg=info.metaData.getString("myMsg");
```

2)在application的应用。
xml代码段:
```


```
java代码段:
```
ApplicationInfo appInfo = this.getPackageManager().getApplicationInfo( getPackageName(),PackageManager.GET_META_DATA);
String msg=appInfo.metaData.getString("myMsg");
```

3)在service的应用。
xml代码段:
```


```
java代码段:
```
ComponentName cn=new ComponentName(this, MetaDataService.class);
ServiceInfo info=this.getPackageManager().getServiceInfo(cn, PackageManager.GET_META_DATA);
String msg=info.metaData.getString("myMsg");
```

4)在receiver的应用。
xml代码段:
```





```
java代码段:
```
ComponentName cn=new ComponentName(context, MetaDataReceiver.class);
ActivityInfo info=context.getPackageManager().getReceiverInfo(cn, PackageManager.GET_META_DATA);
String msg=info.metaData.getString("myMsg");
```

如上中,我只应用了Application层的,并且设置成变量,在gradle中配置需要的参数,例如日志开关、渠道号等。

**1.2 Gson实体类,最好放入同一个包下,方便配置混淆。**

**1.3 handler作为内部类会造成内存泄漏。**
使用静态内部类,并且在内部类中持有外部类的弱引用。

**1.4 ArrayList 和LinkedList区别**
ArrayList是基于数组实现的,LinkedList是基于链表实现的。因此ArrayList适合查找,不适合插入删除;LinkedList相反,适合插入删除,查找效率低。

### 2.UI及资源
**2.1直接在attrs.xml中使用android属性。**
```




```

注意,这里我们是使用已经定义好的属性,不需要去添加format属性(注意声明和使用的区别,差别就是有没有format)。然后在类中这么获取:ta.getString(R.styleable.test_android_text);布局文件中直接android:text="@string/hello_world"即可。

**2.2 EditText不获得焦点**
一个布局文件里第一个EditText将默认获得焦点,如果想让其默认不获得焦点,则:可以在EditText的父级控件中找一个,设置成
```
android:focusable="true"
android:focusableInTouchMode="true"
```
这样,就把EditText默认的行为截断了。

**2.3 onItemClickListener不起作用。**
解决方法:将ListView有点击效果的子控件的焦点取消。android:focusable="false"

**2.4 EditText自定义底部加线。**
```
android:background="@null"
android:drawableBottom="@drawable/line"
```

**2.5 EditText不显示光标**
android:textCursorDrawable="@null"(也可以自定义光标)

**2.6 RelativeLayout中第二个TextView按照第一个TextView对齐,但有的手机中文字明显没有对齐。**
解决方法:在第二个TextView中增加layout_alignBaseline="@id/first_textview"使基线对准。

**2.7 Relative会让子View调用2次onMeasure**
RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure;在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout.

**2.8 Padding or Margin**
RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin.

**2.9 ScrollView嵌套GridView, ListView只显示一行**
如果单独使用GridView和ListView,里面的内容是固定的,底层系统很容易计算出控件要占用的宽高,当外面嵌套一层ScrollView后,就能做上下或左右滑动,但能滑动多少系统不知道,这时就需要你给计算出一个滑动区域给ScrollView。

解决方法:
1)计算出来ListView或者GridView中的子列高度和进行显示:
```
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
((MarginLayoutParams)params).setMargins(15, 15, 15, 15);
listView.setLayoutParams(params);
}
```

2)重写ListView或GridView的onMeasure方法
```
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
```

**2.10 view能够保持在弹出的软键盘上方。**
解决:将该view外边套一个scrollview,弹出软键盘会将该view上滑到软键盘上。

**2.11 dp & px**
120dpi(ldpi低密度屏)   1dp = 0.75px
160dpi(mdpi中密度屏)   1dp = 1px
213dpi(tvdpi电视密度屏)  1dp = 1.33px
240dpi(hdpi高密度屏)   1dp = 1.5px
320dpi(xhdpi极高密度屏)  1dp = 2px

**2.12使用selector反色点击反馈效果(如:背景白色图片黑色,点击后背景黑色图片白色)。**
```


















```

**2.13 Android中application的theme不生效的解决方法**
在Application.java中,attach context的时候,theme并没有被用上。
```
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
```
所以,修复很简单:
```
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
setTheme(mLoadedApk.getApplicationInfo().theme);
}
```

当然,如果你不能修改android系统,又想要在你的application中用这个theme,则需要在你的application的onCreate()中加入:
`setTheme(getApplicationInfo().theme);`

**2.14父布局的layout_width, layout_height不生效**
有的时候我们用inflate加载一个布局,且root参数设置为null,比如在adapter中加载布局的时候。layout_width, layout_height是需要针对父布局设置布局的宽和高,当父布局为null时,就没有作用了。

**2.15设置TextView多行文本可滚动。**
`yourTextView.setMovementMethod(new ScrollingMovementMethod())`

**2.16 recyclerview 在xml中设置宽度match_parent无效。**
adapter填充View时,带上参数ViewGroup parent。
即使用 View view = mInflater.from(mContext).inflate(R.layout.item_fra_main2, parent, false);
不使用 View view = View.inflate(parent.getContext(), R.layout.item_fra_main2, null);

**2.17 ouTouch 和 onTouchEvent区别**
onTouchListener的onTouch方法优先级比onTouchEvent高,会先触发。
假如onTouch方法返回false会接着触发onTouchEvent,反之onTouchEvent方法不会被调用。

**2.18代码设置edittext最大长度**
`mKetEdit.setFilters(new InputFilter[]{new InputFilter.LengthFilter(editMaxLength)});`

### 3. Android Studio
**3.1下载下来的jar包位置**
如foldable-layout-1.0.1-sources.jar:
C:\Users\用户\.gradle\caches\modules-2\files-2.1\com.alexvasilkov\foldable-layout\1.0.1\59a9dd35f8d31de01991ee56b741e9e992914895\foldable-layout-1.0.1-sources.jar

**3.2 Ctrl+鼠标左键点击某Android类名A时,如果找不到A.java,显示的是A.class,可能是未找到API对应的源码位置。**
解决:在C:\Users\{用户}\.AndroidStudio{version}\config\options\jdk.table.xml中,修改提示对应的sourcePath节点。
例如:如果无法关联API 22,则找到节点,修改其子节点sourcePath,添加本地SDK路径:
```



```

**3.3 Preview不显示UI界面,并提示Exception raised during rendering: com/android/util/PropertiesMap.**
解决:换一个preview的工具栏中的API version.(我将24换成23就可以了。)

**3.4 support版本需要和compileSdkVersion相同**

在近大半年的时间里,我陆续参与了4,5个Android项目,在不断探索和解决问题的过程中,将如上这些我认为比较常见或经典的问题记录了下来,作为一点经验的积累同时也分享给大家,希望能解决更多人的问题。

其实作为开发者应该多写写博客,多进行技术交流,但就我个人而言,每天除了睡眠时间,占用最多的就是敲代码的时间了,碰巧今天统计了一下近两个月的代码量是5w多行(包括删改),而且本人才思不济,真的不太擅长写作,所以每篇文章的间隔会很长。

除了以文章的形式进行分享外,我也将平时的这些积累记录在一个工程中:[https://github.com/liujiangchuan/HorseBean](https://github.com/liujiangchuan/HorseBean)
这个工程是我正在逐步完善的一个Android框架,里面引用了很多前人的经验,同时也融入了自己的理解和思想。我计划在下篇文章中,对这个工程进行详细的介绍和说明,希望能够吸引大家来评论和提出意见。

_这次标题又是菜鸟“起飞”之路,没错,除了在工作上作为菜鸟正在努力起飞外,趁着十一的假期加上年假,带着媳妇儿飞去美国度个假,希望一切顺利。也预祝大家国庆长假玩的开心,节日快乐。_

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the issue body, which contains the Android development article and links to its original source and the HorseBean repository. No target file, test, or concrete documentation change is named, so the expected destination and definition of done need to be clarified before work begins.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
documentation
Issue type
Documentation
Difficulty
1/5
Estimated time
Under an hour
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.