实现效果
需求
- Recycle有一个头布局,可以跟随列表进行滑动
- 点击头布局之后可以重新加载列表数据
- 随着头布局的消失,留下一个可点击的布局(该布局在头布局中)
效果类似下图:
淘宝的商品列表,随着我们向下滑动,只会留下综合排序和销量优先这个布局,
当我们点击销量优先的时候便会更新数据。我就是想实现这个效果。我是用下面的
方法实现的,大家如果有更好的方法还请指教。谢谢。
实现思路
- 为RecycleView添加头布局
- 把吸顶布局和RecycleView写在FrameLayout中
- 监听RecycleView的滑动事件(当滑动的距离刚好是头布局的高时,显示吸顶布局)
注意:我在项目中使用了第三方开源库(BaseRecyclerViewAdapterHelper)
该项目的github库:
https://github.com/CymChad/BaseRecyclerViewAdapterHelper
快速入门–>点击
http://blog.csdn.net/pyfysf/article/details/72784134
代码:
MainActivity
public class MainActivity extends AppCompatActivity {
private RecyclerView mRv_list;
private TextView mItem_top;
private int mDy;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mRv_list =
findViewById(R.id.rv_list);
mItem_top = findViewById(R.id.item_top);
mItem_top.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "初始化数据", Toast.LENGTH_SHORT).show();
initData(false);
}
});
initData(true);
}
/**
* 是否设置数据适配器
*
* @param isSetAdapter
*/
private void initData(boolean isSetAdapter) {
//创建模拟数据
List<String> mData = new ArrayList<>();
for (int i = 0; i < 100; i++) {
if (!isSetAdapter) {
mData.add("new message" + i);
} else {
mData.add("message" + i);
}
}
if (isSetAdapter) {
TestAdapter testAdapter = new TestAdapter(R.layout.item_test, mData);
final View hearderView = View.inflate(this, R.layout.header_view, null);
testAdapter.addHeaderView(hearderView);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRv_list.setLayoutManager(linearLayoutManager);
mRv_list.setHasFixedSize(true);
final int viewHeight = getViewHeight(hearderView);
mRv_list.setAdapter(testAdapter);
mRv_list.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (mDy > viewHeight) {
mItem_top.setVisibility(View.VISIBLE);
} else {
mItem_top.setVisibility(View.GONE);
}
mDy += dy;
Log.e("MainActivity", "MainActivity onScrolled(viewHeight)" + viewHeight);
Log.e("MainActivity", "MainActivity onScrolled(mDy)" + mDy);
Log.e("MainActivity", "MainActivity onScrolled(dy)" + dy);
}
});
} else {
TestAdapter adapter = (TestAdapter) mRv_list.getAdapter();
adapter.setNewData(mData);
}
}
/**
* 获取View的高
*
* @param view
* @return px
*/
public int getViewHeight(View view) {
view.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
return view.getMeasuredHeight();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/item_top"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#000"
android:text="Activity布局"
android:textColor="@android:color/white"
android:visibility="gone"/>
</FrameLayout>
header_view.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="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher_background"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher_background"/>
<ImageView
android:id="@+id/item_top"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#F00"/>
</LinearLayout>
item_test.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="100dp">
<TextView
android:id="@+id/tv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@android:color/holo_red_dark"
android:textSize="20sp"
android:textStyle="bold"/>
</LinearLayout>
TestAdapter.java
package top.wintp.juhedatademo.adapter;
import android.support.annotation.Nullable;
import android.widget.BaseAdapter;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
import top.wintp.juhedatademo.R;
/**
* 作者: pyfysf
* <p>
* qq: 337081267
* <p>
* CSDN: http://blog.csdn.net/pyfysf
* <p>
* 个人博客: http://wintp.top
* <p>
* 时间: 2018/01/2018/1/15 19:29
* <p>
* 邮箱: pyfysf@163.com
*/
public class TestAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
public TestAdapter(int layoutResId, @Nullable List<String> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, String item) {
helper.setText(R.id.tv_item, item);
}
}
这样就能实现RecycleView文字吸顶,点击布局刷新数据了。
防淘宝智能排序和销量优先布局。
博主QQ:337081267
如果大家有其他可以实现此功能的方法,还请大家指教小弟。谢谢。