列表粘性分组之按首字母分组国家选区号
Android原生版本
直接先看UI图,效果如下
本来看起来也不难,我就想着上面常用区号那块不动,下面的列表滑动就行,但IOS说他滑动的时候上面也滑上去了,好吧,这也行;但最终效果做出来后,IOS滑动后会有按照国家名称首字母进行粘性分组,好吧,为了提升自己,我也决定做得跟IOS一样,不说废话了,直接上代码
引入流布局控件
//流布局
api 'com.google.android:flexbox:1.0.0'
布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_content"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_area_code_pop_height"
app:defaultColor="@color/white"
app:topLeftRadius="@dimen/dp_10"
app:topRightRadius="@dimen/dp_10"
tools:background="@color/white">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:paddingVertical="@dimen/dp_20"
android:text="@string/sel_international_code"
android:textColor="@color/col_3a3b3d"
android:textSize="@dimen/sp_18" />
<com.yunqu.quyun_res.widget.StatusLayout
android:id="@+id/status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
app:status="LOADING"
app:toolsStatus="NORMAL">
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:layout_status="LOADING" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_status="NORMAL">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_general"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/dp_20"
android:paddingVertical="@dimen/dp_10"
tools:itemCount="4"
tools:listitem="@layout/item_general_code" />
</FrameLayout>
</com.yunqu.quyun_res.widget.StatusLayout>
<View
android:id="@+id/v_divider"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0_5"
android:layout_above="@id/tv_cancel"
android:background="@color/col_e0e7ee" />
<Button
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/white"
android:gravity="center"
android:paddingVertical="@dimen/dp_17"
android:text="@string/cancel"
android:textColor="@color/col_3a3b3d"
android:textSize="@dimen/sp_16"
app:textPressedColor="@color/col_acb2b8" />
<com.yunqu.quyun_res.widget.TenXuLetterBar
android:id="@+id/txlb"
android:layout_width="@dimen/dp_15"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:layout_alignBottom="@id/v_divider"
android:layout_alignParentEnd="true"
android:layout_marginTop="@dimen/dp_70"
android:layout_marginEnd="@dimen/dp_20"
android:layout_marginBottom="@dimen/dp_10"
android:minHeight="@dimen/dp_area_code_mh"
app:txlb_item_background_def="@drawable/bg_letter_def"
app:txlb_item_background_sel="@drawable/bg_letter_sel"
app:txlb_item_text_color_def="@color/col_9b9b9b"
app:txlb_item_text_color_sel="@color/white" />
<TextView
android:id="@+id/tv_letter"
android:layout_width="@dimen/dp_55"
android:layout_height="@dimen/dp_55"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:background="@drawable/bg_circle_80000000"
android:gravity="center"
android:textColor="@color/white"
android:textSize="18sp"
android:visibility="gone"
tools:visibility="visible" />
</RelativeLayout>
item_common_code.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/dp_10"
tools:ignore="MissingDefaultResource">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_commons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
tools:itemCount="2"
tools:listitem="@layout/item_common_code" />
</FrameLayout>
item_common_code_tip.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="MissingDefaultResource">
<TextView
android:id="@+id/tv_common_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/common_code"
android:textColor="@color/col_9b9b9b"
android:textSize="@dimen/sp_14" />
</FrameLayout>
item_general_code.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="@dimen/dp_12"
android:includeFontPadding="false"
android:textColor="@color/col_111212"
android:textSize="@dimen/sp_14"
tools:text="中国大陆+86" />
</LinearLayout>
item_general_code_group.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="MissingDefaultResource">
<LinearLayout
android:id="@+id/ll_letter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="UselessParent">
<TextView
android:id="@+id/tv_letter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/col_111212"
android:textSize="@dimen/sp_14"
android:textStyle="bold"
tools:text="A" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0_5"
android:layout_marginTop="@dimen/dp_10"
android:background="@color/col_e0e7ee" />
</LinearLayout>
</LinearLayout>
其中com.yunqu.quyun_res.widget.StatusLayout控件是自定义的一个FrameLayout状态控件,这里就不放出来了,其实主要就是控制加载数据过程中的切换,根据逻辑用GONE和VISIBLE也是一样的
com.yunqu.quyun_res.widget.TenXuLetterBar控件代码如下
public class TenXuLetterBar extends View {
private static final String TAG = "TenXuLetterBar";
// private final List<String> mLetters = new ArrayList<>();
private final String[] mLettersHadWell = new String[]{
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"
, "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#"};
private final String[] mLetters = new String[]{
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"
, "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
private final Paint mPaint;
private Drawable mItemBackgroundDef;
private Drawable mItemBackgroundSel;
private final int mItemTextColorDef;
private final int mItemTextColorSel;
private final boolean mNeedWell;
// private int mLetterWidth;
private int mLetterIndex = -1;
private OnLetterChangeListner onLetterChangeListener;//选中字母后的回调
public TenXuLetterBar(Context context) {
this(context, null);
}
public TenXuLetterBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TenXuLetterBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray =
context.obtainStyledAttributes(attrs, R.styleable.TenXuLetterBar);
mItemBackgroundDef = typedArray.getDrawable(