前言
使用RecyclerView实现通讯录/选择国家地区功能,点击字母指定位置的数据置顶显示
逻辑
采用两个RecyclerView进行联动,左边显示数据,右边显示字母。计算右边的RecyclerView手指滑动过程中的position,需计算每个item的高度,再用屏幕高度去除这个高度得到一个因素,用motionEvent.getY()除这个因素得到当前的位置currentPosition。话不多数,上代码:
/**
* Created by 小跑一年
* on 2020/5/06
* des: 选择国家地区
*/
public class SelectCountryAct extends AppCompatActivity {
@BindView(R.id.rv_content)
RecyclerView rvContent;
@BindView(R.id.rv_letter)
RecyclerView rvLetter;
private Unbinder mUnbinder;
private List<SelectCountryModel> dataList;
private List<String> strList;
private List<Integer> posList;
private int perTextHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_country);
mUnbinder = ButterKnife.bind(this);
perTextHeight = ScreenUtils.getScreenHeight(SelectCountryAct.this) / ScreenUtils.dp2px(SelectCountryAct.this, 16);
initData(); //数据源
initWidget();
}
@SuppressLint("ClickableViewAccessibility")
private void initWidget() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
rvContent.setLayoutManager(linearLayoutManager);
rvSearchContent.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
rvLetter.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
CommonRecycleviewAdapter adapter = new CommonRecycleviewAdapter<SelectCountryModel>(dataList, SelectCountryAct.this, R.layout.item_select_country) {
@Override
protected void onBindView(RecycleViewHolder holder, int position) {
View viewLine = holder.getView(R.id.view_line);
TextView tvCountryName = holder.getView(R.id.tv_country_name);
TextView tvCountryNum = holder.getView(R.id.tv_country_num);
TextView tvCountryLetter = holder.getView(R.id.tv_country_letter);
tvCountryName.setText(dataList.get(position).getCountryName());
tvCountryNum.setText(dataList.get(position).getCountryCode());
tvCountryLetter.setText(dataList.get(position).getShortName());
if (position > 0 && dataList.get(position).getShortName().equals(dataList.get(position - 1).getShortName())) {
tvCountryLetter.setVisibility(View.GONE);
viewLine.setVisibility(View.VISIBLE);
} else {
viewLine.setVisibility(View.GONE);
tvCountryLetter.setVisibility(View.VISIBLE);
}
}
};
rvContent.setAdapter(adapter);
CommonRecycleviewAdapter adapter2 = new CommonRecycleviewAdapter<String>(strList, SelectCountryAct.this, R.layout.item_select_country_letter) {
@Override
protected void onBindView(RecycleViewHolder holder, int position) {
TextView tvCountryLetter = holder.getView(R.id.tv_country_letter);
tvCountryLetter.setText(strList.get(position));
}
};
rvLetter.setAdapter(adapter2);
adapter.setOnItemClickListener(new CommonRecycleviewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) { //选中国家地区信息
}
@Override
public void onItemLongClick(View view, int position) {
}
});
adapter2.setOnItemClickListener(new CommonRecycleviewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//保证点击后数据置顶显示,使用rvLetter.scrollToPosition(position)或rvLetter.smoothScrollToPosition(position),左边数据显示在屏幕底部
linearLayoutManager.scrollToPositionWithOffset(posList.get(position), 0);
}
@Override
public void onItemLongClick(View view, int position) {
}
});
rvLetter.setOnTouchListener(new View.OnTouchListener() { //处理手指上下滑动获取position
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float y = motionEvent.getY();
int currentPosition = (int) (y / perTextHeight);
currentPosition = currentPosition < 0 ? 0 : currentPosition < posList.size() ? currentPosition : posList.size() - 1;
linearLayoutManager.scrollToPositionWithOffset(posList.get(currentPosition), 0);
return true;
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mUnbinder != null) {
mUnbinder.unbind();
}
}
}
activity_select_country.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/clo_f8f8f8"
android:focusable="true"
android:focusableInTouchMode="true">
<!-- android:textCursorDrawable="@color/black_4D" -->
<EditText
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="@dimen/distance_36dp"
android:layout_marginLeft="@dimen/distance_12dp"
android:layout_marginTop="@dimen/distance_8dp"
android:layout_marginRight="@dimen/distance_12dp"
android:layout_marginBottom="@dimen/distance_8dp"
android:autofillHints="no"
android:background="@drawable/bg_white_4dp"
android:hint="@string/search_country"
android:imeOptions="actionSearch"
android:inputType="text"
android:paddingLeft="@dimen/distance_40dp"
android:textColor="@color/black_20"
android:textColorHint="@color/black_4D"
android:textSize="14dp"
android:theme="@style/MyEditText" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/distance_12dp"
android:layout_marginTop="@dimen/distance_6dp"
android:src="@mipmap/search" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/et_search"
android:scrollbars="none" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@+id/et_search"
android:layout_alignParentRight="true"
android:background="@color/transparent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_letter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@color/transparent"
android:scrollbars="none" />
</RelativeLayout>
<View
android:id="@+id/view_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/et_search"
android:background="@color/black_66"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_search_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/et_search"
android:background="@color/white"
android:scrollbars="none"
android:visibility="gone" />
</RelativeLayout>
item_select_country.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
<View
android:id="@+id/view_line"
android:layout_marginLeft="@dimen/distance_12dp"
android:background="@color/clo_1A221E1F"
android:layout_width="match_parent"
android:layout_height="@dimen/height_1px"/>
<TextView
android:id="@+id/tv_country_letter"
android:layout_width="match_parent"
android:layout_height="32dp"
android:background="@color/clo_f8f8f8"
android:gravity="center_vertical"
android:paddingLeft="@dimen/distance_12dp"
android:textColor="@color/black_99"
android:textSize="16dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/distance_12dp">
<TextView
android:id="@+id/tv_country_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:textColor="@color/black_20"
android:textSize="16dp" />
<TextView
android:id="@+id/tv_country_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:background="@color/white"
android:paddingRight="@dimen/distance_30dp"
android:textColor="@color/black_4D"
android:textSize="14dp" />
</RelativeLayout>
</LinearLayout>
item_select_country_letter.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_country_letter"
android:textColor="@color/clo_DD8675"
android:paddingRight="@dimen/distance_9dp"
android:paddingLeft="@dimen/distance_12dp"
android:textSize="12dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="@dimen/distance_16dp" />
</LinearLayout>
后记
后续跟进中.....