0%

新项目问题汇总

前言

最近两个月,一直在做新项目,期间遇到了不少问题,在此备忘一下吧

问题汇总

1. Scrollview嵌套RecycleView后,滑动卡顿的问题

1
recyclerView.setNestedScrollingEnabled(false);

当然也可以这样解决:

1
2
3
4
5
6
7
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false) {  
@Override
public boolean canScrollVertically() {
return false;
}
};
recyclerview.setLayoutManager(linearLayoutManager);

2. 自定义actionbar去掉左右空白

原因

actionbar样式中默认有两个属性contentInsetStart/contentInsetEnd分别控制左右边距,默认是16dp

解决方案
  • 方法1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    View view = LayoutInflater.from(this).inflate(R.layout.custom_actionbar,null);  
    ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT,
    ActionBar.LayoutParams.MATCH_PARENT);
    layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_HORIZONTAL;
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setCustomView(view, layoutParams);
    ViewParent parent = view.getParent();
    if (parent instanceof Toolbar) {
    // 解决系统actionbar左右留有16dp空白问题
    ((Toolbar) parent).setContentInsetsAbsolute(0, 0);
    }
  • 方法2

经过网上搜索得出答案, 原来需要重写为0dp即可解决。

1
2
3
4
5
6
7
8
9
10
11
<item name="contentInsetStart"><item name="contentInsetEnd">
下面是我在style.xml文件中自定义actionbarstyle的示例代码

<style name="ActionBarBaseStyle" parent="@style/Widget.AppCompat.Light.ActionBar">
<item name="background">@color/actionbar_background</item>
<item name="titleTextStyle">@style/TitleStyle</item>
<item name="android:icon">@android:color/transparent</item>
<item name="subtitleTextStyle">@style/SubTitle</item>
<item name="contentInsetStart">0dp</item>
<item name="contentInsetEnd">0dp</item>
</style>

3. 隐藏Listview和RecyclerView 滑动边界的阴影

1
android:overScrollMode="never"

4. RelativeLayout @id/ 和@+id/的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Button
android:text="@string/menu_start"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="70dp"
android:layout_alignLeft="@id/btn_menu_scores"
android:layout_alignRight="@id/btn_menu_scores"
android:textSize="30dp"
android:textStyle="bold"
android:layout_marginBottom="20dp"
android:id="@+id/btn_menu_start"
/>
<Button
android:text="@string/menu_scores"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="30dp"
android:layout_marginBottom="20dp"
android:id="@+id/btn_menu_scores"/>

xml的解析是从上往下扫描的,如果id为btn_menu_scores的View在当前View下方,则会报如下错误:

No resource found that matches the given name (at ‘layout_alignLeft’ with value ‘@id/btn_menu_scores’)
此时把@id/改成@+id/就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Button
android:text="@string/menu_start"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="70dp"
android:layout_alignLeft="@+id/btn_menu_scores"
android:layout_alignRight="@+id/btn_menu_scores"
android:textSize="30dp"
android:textStyle="bold"
android:layout_marginBottom="20dp"
android:id="@+id/btn_menu_start"
/>
<Button
android:text="@string/menu_scores"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="30dp"
android:layout_marginBottom="20dp"
android:id="@+id/btn_menu_scores"/>

5. EditText输入表情

  • 方法1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CharSequence charSequence = Html.fromHtml(html,  
    new ImageGetter() {

    @Override
    public Drawable getDrawable(String source) {
    // TODO Auto-generated method stub
    Drawable drawable = getResources().getDrawable(
    Integer.parseInt(source));
    // 设置drawable的大小。设置为实际大小
    drawable.setBounds(0, 0,
    drawable.getIntrinsicWidth(),
    drawable.getIntrinsicHeight());
    return drawable;
    }
    }, null);
    textView.setText(charSequence);
  • 方法2
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),  
    images[randomId]);
    // 得到SpannableString对象,主要用于拆分字符串
    SpannableString spannableString = new SpannableString("image");
    // 得到ImageSpan对象
    ImageSpan imageSpan = new ImageSpan(MainActivity.this, bitmap);
    // 调用spannableString的setSpan()方法
    spannableString.setSpan(imageSpan, 0, 5,
    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    // 给EditText追加spannableString
    editText.append(spannableString);

6. ScrollView嵌套RecyclerView自动滑动问题

这貌似是RecyclerView的一个Bug,具体请看这里:
https://issuetracker.google.com/issues/37120277

https://stackoverflow.com/questions/37782485/android-prevent-nested-recyclerview-from-automatically-repositioning

ScrollView里面套一个RecyclerView使用时,会发现当RecyclerView填充满数据后,ScrollView会自动滑动到RecyclerView所在位置。原因是RecyclerView抢占了焦点,解决方案当然也多种多样了,能够阻止RecyclerView获取焦点即可。因为我的布局中是ScrollView包含LinearLayout,LinearLayout又包含RecyclerView,所以在LinearLayout中添加如下属性即可

1
android:descendantFocusability="blocksDescendants"

7. SharePreference升级兼容问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void setSettingTextSize(int time) {
defaultConfig.setValue(KEY_SETTING_TEXT_SIZE, time);
}
public static int getSettingTextSize(int defaultValue) {
return defaultConfig.getValue(KEY_SETTING_TEXT_SIZE, defaultValue);
}
public static void setSettingTextSizeNew(int time) {
defaultConfig.setValue(KEY_SETTING_TEXT_SIZE_NEW, time);
}
public static int getSettingTextSizeNew(int defaultValue) {
int currentValue = defaultConfig.getValue(KEY_SETTING_TEXT_SIZE_NEW, defaultValue);
// 说明可能是第一次使用新版本,则需要兼容一下老版本
if (currentValue == defaultValue) {
// milk之前存放的字体顺序是特大-0、大-1、中-2、小-3,milk之后改成小-0、中-1、大-2、特大-3
int oldValue = getSettingTextSize(-1);
if (oldValue > -1) {
defaultConfig.delValue(KEY_SETTING_TEXT_SIZE);
setSettingTextSizeNew(3 - oldValue);
// 此处改变一下映射关系
return 3 - oldValue ;
}
}
return currentValue;
}

8. IllegalStateException: Can not perform this action after onSaveInstanceState

  • 解决方法1

重写activity onSaveInstanceState方法,并且不要调用父类方法

1
2
3
4
@Override
protected void onSaveInstanceState(Bundle outState) {
//No call for super(). Bug on API Level > 11.
}
  • 解决方法2

重写activity onSaveInstanceState方法,并且在调用父类方法之前,随意传一个参数,如下

1
2
3
4
5
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
super.onSaveInstanceState(outState);
}

参考:
https://stackoverflow.com/questions/7469082/getting-exception-illegalstateexception-can-not-perform-this-action-after-onsa/10261438#10261438

http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

9. 获取java 泛型T对应class

1
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

参考:http://blog.csdn.net/u013692310/article/details/53706283

10. 布局Preview失效

解决方案:删除工程根目录下build目录,然后重新build一次即可。

11. 动态设置layout_marginTop

1
2
3
4
5
6
7
8
9
ViewGroup.LayoutParams params = mBackView.getLayoutParams();
if (params instanceof ViewGroup.MarginLayoutParams) {
((ViewGroup.MarginLayoutParams) params).setMargins(
0,
SystemUtils.getStatusBarHeight(), // marginTop
0,
0);
}
mActionBarView.setLayoutParams(params);