Android 安卓技术分享Android开发Android技术知识

Android开发问题和经验总结(不断更新中)

2019-08-19  本文已影响2人  ayvytr

Android开发问题和经验总结(不断更新中)

安卓常见问题,Bug等以及解答,欢迎大家更新和指正!!!

View 问题

TextView

singleLine过时了,使用lines代替。maxLines=“1”不能限制文本只显示一行

EditText

Java代码中调用了setFilters,会覆盖布局中maxLength属性,除非同时设置了LengthFilter

RecyclerView

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position...

RecyclerView绑定的 List 对象在更新数据之前进行了 clear,而这时紧接着迅速上滑 RecyclerView,就会造成崩溃,属于RecyclerView内部异常。

RecyclerView在多层嵌套的内容中,即使设置了wrap_content或者match_parent,但是数据项还是只显示1行,Item高度也不是wrap_content

使用可以让RecyclerView显示全的控件进行包裹,推荐使用NestedScrollView。(本人在项目中遇到这个问题,Recyclerview外层是多层LinearLayout, CardView等布局,还要在外层加上下拉刷新的功能。网上多种解决方案都试过,也没有采用inflate(layoutId, null, false)加载Item的方法,因为封装过Adapter再改代价很大。最后的解决方案是:在RecyclerView外层布局包裹NestedScrollView,禁用RecyclerView滑动,使用NestedScrollView的滑动即可[本人使用的下拉刷新是SmartRefreshLayout,内部使用NestedScrollView可以正常滑动,问题解决])

ScrollView嵌套RecyclerView的显示不全,滑动卡顿,夺取了焦点导致页面启动时RecyclerView上方布局没显示问题

有问题的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

            <!--页面启动时,TextView未显示,焦点被RecyclerView获取-->
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/_200dp"
                android:gravity="center"
                android:text="Header"
                android:textColor="@color/aero"
                android:textSize="@dimen/_50sp"/>

            <!--没有android:nestedScrollingEnabled="false"时,滑动冲突,-->
            <!--有这个属性时,ScrollView无法滑动,整个ScrollView只能滑动一点-->
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv"
                android:nestedScrollingEnabled="false"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

        </LinearLayout>
    </ScrollView>
</LinearLayout>

滑动卡顿问题:

recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);
或者
android:nestedScrollingEnabled="false"

RecyclerView夺取焦点问题:外层布局需要增加属性

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

显示不全的问题:使用NestedScrollView代替ScrollView

//没有问题的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <!--页面启动时,TextView未显示,焦点被RecyclerView获取-->
            <TextView
                android:layout_width="match_parent"
                android:layout_height="@dimen/_200dp"
                android:gravity="center"
                android:text="Header"
                android:textColor="@color/aero"
                android:textSize="@dimen/_50sp"/>

            <!--没有android:nestedScrollingEnabled="false"时,滑动冲突,-->
            <!--有这个属性时,ScrollView无法滑动,整个ScrollView只能滑动一点-->
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv"
                android:nestedScrollingEnabled="false"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</LinearLayout>

DiffUtil.Callback RecyclerView动态更新/增减数据需要实现的类

部分(partial)绑定vs完整(full)绑定
payloads 参数 是一个从(notifyItemChanged(int, Object)或notifyItemRangeChanged(int, int, Object))里得到的合并list。
如果payloads list 不为空,那么当前绑定了旧数据的ViewHolder 和Adapter, 可以使用 payload的数据进行一次 高效的部分更新。
如果payload 是空的,Adapter必须进行一次完整绑定(调用两参方法)。

需要实现的方法:DiffUtil.Callback:public Object getChangePayload(int oldItemPosition, int newItemPosition), RecyclerView.Adapter:public void onBindViewHolder(VH holder, int position, List<Object> payloads)

ScrollView

滚动到顶部或者底部 :

scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部

scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部

滚动到顶部的三种方式:

ScrollView.scrollTo(``0``,``0``);``//直接置顶,瞬间回到顶部,没有滚动过程,其中Y值可以设置为大于0的值,使Scrollview停在指定位置。
ScrollView.fullScroll(View.FOCUS_UP);``//类似于手动拖回顶部,有滚动过程
ScrollView.smoothScrollTo(``0``, ``0``);``//类似于手动拖回顶部,有滚动过程,其中Y值可以设置为大于0的值,使Scrollview停在指定位置。

ViewPager

Item切换重建(主要是和Fragment搭配使用时,切换到第三个页面,第一个页面销毁)

通过setOffscreenPageLimit防止频繁销毁(setOffscreenPageLimit注释:设置当前page左右两侧应该被保持的page数量,超过这个限制,page会被销毁重建(只是销毁视图),onDestroy-onCreateView,但不会执行onDestroy。尽量维持这个值小,特别是有复杂布局的时候,因为如果这个值很大,就会占用很多内存,如果只有3-4页的话,可以全部保持active,可以保持page切换的顺滑

Activity等系统组件

Activity切换时,短暂白屏问题,主要是启动singleTask或者singleInstance标志的Activity,同时关闭当前Activity,大概率出现这个问题

Activity theme加上 **<item name="android:windowDisablePreview">true</item> ** 即可。

这个标志应该也可以 <item name="android:windowIsTranslucent">true</item> ,然后onCreate应该需要去掉这个标志。

上一篇下一篇

猜你喜欢

热点阅读