您的位置:首页 > 其它

Recyclerview的一些个人理解与使用(五)Recyclerview的联动,时间选择的实现

2017-05-05 14:53 976 查看
目录:

Recyclerview的一些个人理解与使用(一)adapter的简单封装

Recyclerview的一些个人理解与使用(二)实现一个简单的列表界面

Recyclerview的一些个人理解与使用(三)列表中的计时器

Recyclerview的一些个人理解与使用(四)在界面中实现侧边栏效果

Recyclerview的一些个人理解与使用(五)Recyclerview的联动,时间选择的实现

Recyclerview的一些个人理解与使用(六)Recyclerview的分段加载

Recyclerview的一些个人理解与使用(七)Recyclerview的嵌套与增加删除

我们的前端还在实现产品的那个奇怪需求,刚好闲着,我也顺便多些两篇博客,照例,放上上一篇博客的地址:

http://blog.csdn.net/ljwztn/article/details/71108509

在上一篇博客中我们实现了一个界面中的侧边栏效果,因为本人实在懒得找太多图片,效果比较简陋。本篇我们将会实现一个Recyclerview的联动,做一个时间选择的功能,废话不多说,先上效果图



滑动右边Recyclerview,左边随着顶部第一个可item内容变化,点击右边周的item,弹出选中的整体时间。选中左侧item,右面Recyclerview跳转到对应年份的item。

先列出我们所要的数据格式,应该为一个数组中包含了年份,而年份又对应了一个周的数组,创建数据格式:

/**
*  Created by ztn on 2017/5/3
*/

public class LinkageBean {
public List<Data> data;

public static class Data {
public String year;
public List<Weeks> weeks;

public static class Weeks {
//            public String weekId;       //网络请求时的幕后工作者
public String weekTitle;    //作为界面中的展示内容
}
}
}


然后我们边说思路,边实现效果。

先是左侧的侧边栏,这个与我们上篇文章的侧边栏比较相似,都是item为checkBox,方便我们在选中item时带来的背景颜色的改变,让人容易区分,adapter代码:

/**
* Created by ztn on 2017/5/3
*/

public class LinkageYearRecyclerViewAdapter extends SimpleRecycleViewAdapter<LinkageBean.Data, LinkageYearRecyclerViewHolder> {

private OnClickChooseListener onClickChooseListener;
private int checked = 0;

public LinkageYearRecyclerViewAdapter(Context context, List<LinkageBean.Data> listData) {
super(context, listData);
}

public void setChecked(int checked) {
this.checked = checked;
}

/**
* 创建View
*
* @param parent
* @return
*/
@Override
protected LinkageYearRecyclerViewHolder onCreateItemViewHolder(ViewGroup parent) {
return new LinkageYearRecyclerViewHolder(inflater.inflate(R.layout.activity_linkage_leftl_year_item, parent, false));
}

public void setOnClickChooseListener(OnClickChooseListener onClickChooseListener) {
this.onClickChooseListener = onClickChooseListener;
}

/**
* 给View设置数据
*
* @param linkageYearRecyclerViewHolder
* @param position
*/
@Override
protected void onBindItemViewHolder(LinkageYearRecyclerViewHolder linkageYearRecyclerViewHolder, int position) {
linkageYearRecyclerViewHolder.initView(context, listData.get(position), onClickChooseListener, checked, position);
}

/**
* 选中事件
*/

public interface OnClickChooseListener {
void onChoose(LinkageBean.Data data, int checked);
}
}


xml与上一篇中的侧边栏类似这里就不在赘述。然后是holder代码:

/**
* Created by ztn on 2017/5/3
*/

public class LinkageYearRecyclerViewHolder extends RecyclerView.ViewHolder {
CheckBox checkBox;

public LinkageYearRecyclerViewHolder(View itemView) {
super(itemView);
checkBox = (CheckBox) itemView.findViewById(R.id.linkage_year_item_cb);
}

public void initView(Context context, final LinkageBean.Data data,
final LinkageYearRecyclerViewAdapter.OnClickChooseListener onClickChooseListener, final int checked,
final int position) {

checkBox.setText(data.year);

checkBox.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.itemclick_bg_year, 0, 0);
boolean isChecked;
isChecked = checked == position;
checkBox.setChecked(isChecked);

if (isChecked) {
checkBox.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.blue));
} else {
checkBox.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.black));
}

itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onClickChooseListener != null)
onClickChooseListener.onChoose(data, position);
}
});
}
}


在holder中,我们对选中的item的背景颜色进行了赋值,以便进行区分。

接着是右侧adapter的代码:

/**
* Created by ztn on 2017/5/3
*/
public class RightAdapter extends SimpleRecycleViewAdapter<LinkageBean.Data, RightAdapterHolder> {

private OnClickItemListener onClickItemListener;

public RightAdapter(Context context, List<LinkageBean.Data> listData) {
super(context, listData);
}

/**
* 创建View
*
* @param parent
* @return
*/
@Override
protected RightAdapterHolder onCreateItemViewHolder(ViewGroup parent) {
return new RightAdapterHolder(inflater.inflate(R.layout.activity_linkage_right_rl_item, parent, false));
}

public void setOnClickItemListener(OnClickItemListener onClickItemListener) {
this.onClickItemListener = onClickItemListener;
}

/**
* 给View设置数据
*
* @param rightAdapterHolder
* @param position
*/
@Override
protected void onBindItemViewHolder(RightAdapterHolder rightAdapterHolder, int position) {
rightAdapterHolder.initView(context, listData.get(position), onClickItemListener,position);
}

public interface OnClickItemListener {
void onClick(LinkageBean.Data data);
}
}


对应的xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="2dp"
android:paddingTop="2dp"
android:focusableInTouchMode="true"
android:focusable="true">

<TextView
android:id="@+id/tv_year"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white_f6"
android:padding="5dp"/>

<android.support.v7.widget.RecyclerView
android:id="@+id/rl_week"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:overScrollMode="ifContentScrolls"
android:scrollbars="vertical"/>

</LinearLayout>


textview对应的显示了年份,底下的Recyclerview用来显示具体的周时间。

holder代码:

/**
* Created by ztn on 2017/5/3
*/
class RightAdapterHolder extends RecyclerView.ViewHolder {

private TextView year;
private RecyclerView recyclerView;
private LinkageWeekAdapter linkageWeekAdapter;
LinkageRecyclerViewActivity linkageRecyclerViewActivity;

RightAdapterHolder(View itemView) {
super(itemView);
year = (TextView) itemView.findViewById(R.id.tv_year);
recyclerView = (RecyclerView) itemView.findViewById(R.id.rl_week);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext()) {
@Override
public boolean canScrollVertically() {
return false;
}

@Override
public boolean canScrollHorizontally() {
return false;
}
});
linkageRecyclerViewActivity = (LinkageRecyclerViewActivity) itemView.getContext();
recyclerView.setHasFixedSize(true);
}

public void initView(final Context context, final LinkageBean.Data data,
final RightAdapter.OnClickItemListener onClickItemListener, final int position) {

year.setText(data.year);
linkageWeekAdapter = new LinkageWeekAdapter(context, data.weeks, position);
recyclerView.setAdapter(linkageWeekAdapter);
linkageWeekAdapter.setOnClickItemListener(new LinkageWeekAdapter.OnClickItemListener() {
@Override
public void onClick(LinkageBean.Data.Weeks data) {
linkageRecyclerViewActivity.setToast(position, data.weekTitle);
}
});
}

}


子Recyclerview是不可滑动的我们重写了layoutmanger,让它不能够滑动,具体的周的显示其实就是一个简单的Recyclerview,与我第二篇文章的内容类似,有疑问的同学可以参考。

接着是我们最重要的代码,Activity的代码:

先放出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="match_parent"
android:background="@color/white"
android:orientation="horizontal"
tools:context=".linkagerecyclerview.LinkageRecyclerViewActivity">

<RelativeLayout
android:layout_width="66dp"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
android:id="@+id/linkage_avtivity_year_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white_f6">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>

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

<android.support.v7.widget.RecyclerView
android:id="@+id/linkage_avtivity_week_rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>

</LinearLayout>


左右两个Recyclerview,很简单。

接下来我们将介绍最重要的代码:

我们首先创建数据,定义一下变量:

List<LinkageBean.Data> datas;
List<LinkageBean.Data.Weeks> weekses;
LinkageBean.Data data;
LinkageBean.Data.Weeks weeks;
//结束的年份
int year = 2017;
//开始被选中的年份是第几个
private int hadselected = 0;


对变量进行赋值,创建数据:

datas = new ArrayList<>();
//时间上倒序排序 i<的东西为左侧显示的年份数量,创建数据
for (int i = 0; i < 30; i++) {
data = new LinkageBean.Data();
data.year = year - i + "年";
weekses = new ArrayList<>();
for (int j = 0; j < 50; j++) {
weeks = new LinkageBean.Data.Weeks();
//采用倒序排序
weeks.weekTitle = "第" + (50 - j) + "周(XX月XX日-YY月YY日)";
//                weeks.weekId = j + ""; //虚拟的对weekId赋值
weekses.add(weeks);
}
data.weeks = weekses;
datas.add(data);
}


初始化adapter:

//年的adapter
linkageYearRecyclerViewAdapter =
new LinkageYearRecyclerViewAdapter(getContext(), datas);
linkageRecyclerViewActivityHolder.year.setAdapter(linkageYearRecyclerViewAdapter);

//右侧的adapter
linkageRecyclerViewActivityHolder.week.setAdapter(rightAdapter);
rightAdapter = new RightAdapter(getContext(), datas);
//获取weekRecyclerview的manager
final LinearLayoutManager weekLinearLayoutManager =
(LinearLayoutManager) linkageRecyclerViewActivityHolder.week.getLayoutManager();


对我们的年adapter添加点击事件:

linkageYearRecyclerViewAdapter.setOnClickChooseListener(new LinkageYearRecyclerViewAdapter.OnClickChooseListener() {
@Override
public void onChoose(LinkageBean.Data data, int checked) {
forceStopRecyclerViewScroll(linkageRecyclerViewActivityHolder.week);
isTouch = false;
weekLinearLayoutManager.scrollToPositionWithOffset(checked, 0);
hadselected = checked;
reTypedata(checked);
}
});


reTypedata代码:

private void reTypedata(int i) {
linkageYearRecyclerViewAdapter.setChecked(i);
linkageYearRecyclerViewAdapter.notifyDataSetChanged();
hadselected = i;
//        linkageRecyclerViewActivityHolder.year.smoothScrollToPosition(i);     //添加滑动事件会稍有卡顿
yearLinearLayoutManager.scrollToPositionWithOffset(i, 0);
}


我们在这里对选中的item进行了check操作,刷新了适配器,并且让Recyclerview跳转到了对应的item。

右侧滑动改变左侧选中,我们对右侧Recyclerview添加滑动监听:

linkageRecyclerViewActivityHolder.week.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isTouch) {
if (dy > 0) {
//上拉
if (hadselected < weekLinearLayoutManager.findFirstVisibleItemPosition()) {
hadselected++;
reTypedata(hadselected);
}
} else if (dy < 0) {
//下滑
if (hadselected > weekLinearLayoutManager.findFirstVisibleItemPosition()) {
hadselected--;
reTypedata(hadselected);
}
}
}
}
});


这里,我们监听了右侧第一个可见的item根据具体情况对左侧的选中进行了改变,怎么样,是不是感觉实现起来没有那么复杂。

以下是完整的Activity代码:

/**
* Created by ztn on 2017/5/3
*/
public class LinkageRecyclerViewActivity extends BaseActivity {
LinkageRecyclerViewActivityHolder linkageRecyclerViewActivityHolder;

List<LinkageBean.Data> datas;
List<LinkageBean.Data.Weeks> weekses;
LinkageBean.Data data;
LinkageBean.Data.Weeks weeks;

//左侧年的adapter
LinkageYearRecyclerViewAdapter linkageYearRecyclerViewAdapter;
//右侧的adapter
RightAdapter rightAdapter;

//结束的年份
int year = 2017;
//开始被选中的年份是第几个
private int hadselected = 0;

//年份是否被点击
private boolean isTouch;

CustomSGLayoutManager yearLinearLayoutManager;

public static Intent newIntent(Context context) {
return new Intent(context, LinkageRecyclerViewActivity.class);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linkage);
linkageRecyclerViewActivityHolder = new LinkageRecyclerViewActivityHolder(this);
datas = new ArrayList<>();
//时间上倒序排序 i<的东西为左侧显示的年份数量,创建数据
for (int i = 0; i < 30; i++) {
data = new LinkageBean.Data();
data.year = year - i + "年";
weekses = new ArrayList<>();
for (int j = 0; j < 50; j++) {
weeks = new LinkageBean.Data.Weeks();
//采用倒序排序
weeks.weekTitle = "第" + (50 - j) + "周(XX月XX日-YY月YY日)";
//                weeks.weekId = j + ""; //虚拟的对weekId赋值
weekses.add(weeks);
}
data.weeks = weekses;
datas.add(data);
}
yearLinearLayoutManager = new CustomSGLayoutManager(getContext());//实例化自定义类
yearLinearLayoutManager.setSpeedSlow(0.3f);//设置其速度因子
linkageRecyclerViewActivityHolder.year.setLayoutManager(yearLinearLayoutManager);

linkageYearRecyclerViewAdapter = new LinkageYearRecyclerViewAdapter(getContext(), datas);
linkageRecyclerViewActivityHolder.year.setAdapter(linkageYearRecyclerViewAdapter);
//获取yearRecyclerview的manager

rightAdapter = new RightAdapter(getContext(), datas);
linkageRecyclerViewActivityHolder.week.setAdapter(rightAdapter);
//获取weekRecyclerview的manager
final LinearLayoutManager weekLinearLayoutManager =
(LinearLayoutManager) linkageRecyclerViewActivityHolder.week.getLayoutManager();

//年份点击时所发生的事件
linkageYearRecyclerViewAdapter.setOnClickChooseListener(new LinkageYearRecyclerViewAdapter.OnClickChooseListener() {
@Override
public void onChoose(LinkageBean.Data data, int checked) {
forceStopRecyclerViewScroll(linkageRecyclerViewActivityHolder.week);
isTouch = false;
weekLinearLayoutManager.scrollToPositionWithOffset(checked, 0);
hadselected = checked;
reTypedata(checked);
}
});

linkageRecyclerViewActivityHolder.week.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event != null) {
isTouch = true;
}
return false;
}
});

linkageRecyclerViewActivityHolder.week.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isTouch) {
if (dy > 0) {
//上拉
if (hadselected < weekLinearLayoutManager.findFirstVisibleItemPosition()) {
hadselected++;
reTypedata(hadselected);
}
} else if (dy < 0) {
//下滑
if (hadselected > weekLinearLayoutManager.findFirstVisibleItemPosition()) {
hadselected--;
reTypedata(hadselected);
}
}
}
}
});
reTypedata(hadselected);
}

//停止滑动
public static void forceStopRecyclerViewScroll(RecyclerView mRecyclerView) {
mRecyclerView.dispatchTouchEvent(MotionEvent.obtain(1,
1, MotionEvent.ACTION_DOWN, mRecyclerView.getWidth(), mRecyclerView.getHeight(), 0));
}

private void reTypedata(int i) {
linkageYearRecyclerViewAdapter.setChecked(i);
linkageYearRecyclerViewAdapter.notifyDataSetChanged();
hadselected = i;
//        linkageRecyclerViewActivityHolder.year.smoothScrollToPosition(i);     //添加滑动事件会稍有卡顿
yearLinearLayoutManager.scrollToPositionWithOffset(i, 0);
}

public void setToast(int yearPosition, String week) {
Toast.makeText(getContext(), "选中了第" + datas.get(yearPosition).year + week, Toast.LENGTH_SHORT).show();
//        finish(); //实际需求中可能需要关闭改界面
reTypedata(yearPosition);
}
}


ok,到这里我们就实现了一个联动的Recyclerview,效果也还可以。

项目地址:

https://github.com/Liveinadream/RecyclerViewDemo#recyclerviewdemo

如有疑问大家可以添加 121606151 这个qq群@Crazy(即本人)即可,欢迎大家前来交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息