笔记 来源阳光沙滩:拉大锯
关于适配器:
记几个不常用的方法解释,
RecyclerView.Adapter<RecyclerView.ViewHolder>
public int getItemViewType(int position)
这个方法是用来获取item控件的类型,根据position来找。比如一个列表,最后两个和第一个要显示一张大图,其他的内容正常显示,就可以根据这个position来返回一个int的类型的值,在渲染item的时候,根据类型来设置数据即可
数据更新时候调用的方法
//数据更新时候调用,全部更细 ondraw()
notifyDataSetChanged();
//还可以指定更新:
public final void notifyItemChanged(int position)
//还可以指定范围更新,从哪里开始到哪里结束,更新多少个item
public final void notifyItemRangeChanged(int positionStart, int itemCount)
ListView效果:
item_list_view;
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--CardView实现分割线效果-->
<androidx.cardview.widget.CardView
android:background="#fff"
app:cardUseCompatPadding="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="90dp">
<ImageView
android:id="@+id/list_view_icon"
android:scaleType="fitXY"
android:padding="10dp"
android:src="@mipmap/thumb01"
android:layout_width="90dp"
android:layout_height="90dp"/>
<TextView
android:id="@+id/list_view_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="我是标题"
android:layout_toRightOf="@id/list_view_icon"
android:layout_marginLeft="30dp"
android:textSize="30sp"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
ListViewAdapter:
package com.example.recyleviewdemo.adapters;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.recyleviewdemo.R;
import com.example.recyleviewdemo.beans.ItemBean;
import java.util.List;
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.InnerHolder> {
private final List<ItemBean> mData;
public ListViewAdapter(List<ItemBean> mData) {
this.mData = mData;
}
/**
* 这个方法用于创建条目View
* @param parent
* @param viewType
* @return
*/
@NonNull
@Override
public ListViewAdapter.InnerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//两个步骤
//1.拿到数据 2.创建InnerHolder
View view = View.inflate(parent.getContext(), R.layout.item_list_view,null);
InnerHolder innerHolder = new InnerHolder(view);
return innerHolder;
}
/**
* 这个方法用户绑定holder,一般用来设置数据
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(@NonNull ListViewAdapter.InnerHolder holder, int position) {
//绑定数据
ItemBean itemBean = mData.get(position);
holder.setData(itemBean);
}
@Override
public int getItemCount() {
if(mData!=null){
return mData.size();
}
return 0;
}
public class InnerHolder extends RecyclerView.ViewHolder {
private ImageView icon;
private TextView title;
public InnerHolder(@NonNull View itemView) {
super(itemView);
//找到条目的控件
icon = itemView.findViewById(R.id.list_view_icon);
title = itemView.findViewById(R.id.list_view_title);
}
/*
* 设置数据
* */
public void setData(ItemBean itemBean){
icon.setImageResource(itemBean.icon);
title.setText(itemBean.title);
}
}
}
GridView效果:
item_grid_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/grid_view_icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="@mipmap/thumb01"
/>
<TextView
android:id="@+id/grid_view_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/grid_view_icon"
android:textSize="20sp"
android:text="@string/app_name"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
package com.example.recyleviewdemo.adapters;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.recyleviewdemo.R;
import com.example.recyleviewdemo.beans.ItemBean;
import java.util.List;
public class GridViewAdapter extends RecyclerView.Adapter<GridViewAdapter.InnerHolder> {
private final List<ItemBean> data;
public GridViewAdapter( List<ItemBean> data){
this.data = data;
}
@NonNull
@Override
public GridViewAdapter.InnerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = View.inflate(parent.getContext(), R.layout.item_grid_view,null);
InnerHolder innerHolder = new InnerHolder(view);
return innerHolder ;
}
@Override
public void onBindViewHolder(@NonNull GridViewAdapter.InnerHolder holder, int position) {
holder.setData(data.get(position));
}
@Override
public int getItemCount() {
if (data!=null){
return data.size();
}
return 0;
}
public class InnerHolder extends RecyclerView.ViewHolder {
private ImageView icon;
private TextView title;
public InnerHolder(@NonNull View itemView) {
super(itemView);
icon = itemView.findViewById(R.id.grid_view_icon);
title = itemView.findViewById(R.id.grid_view_title);
}
public void setData(ItemBean itemBean){
icon.setImageResource(itemBean.icon);
title.setText(itemBean.title);
}
}
}
menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="ListView效果" android:id="@+id/list_view">
<menu>
<item android:id="@+id/list_view_vertical_stander"
android:title="垂直标准"/>
<item android:id="@+id/list_view_vertical_reverse"
android:title="垂直反向"/>
<item android:id="@+id/list_view_horizontal_stander"
android:title="水平标准"/>
<item android:id="@+id/list_view_horizontal_reverse"
android:title="水平反向标准"/>
</menu>
</item>
<item android:title="GridView效果" android:id="@+id/grid_view">
<menu>
<item android:id="@+id/grid_view_vertical_stander"
android:title="垂直标准"/>
<item android:id="@+id/grid_view_vertical_reverse"
android:title="垂直反向"/>
<item android:id="@+id/grid_view_horizontal_stander"
android:title="水平标准"/>
<item android:id="@+id/grid_view_horizontal_reverse"
android:title="水平反向标准"/>
</menu>
</item>
<item android:title="瀑布流效果" android:id="@+id/stagger_view">
<menu>
<item android:id="@+id/stagger_view_vertical_stander"
android:title="垂直标准"/>
<item android:id="@+id/stagger_view_vertical_reverse"
android:title="垂直反向"/>
<item android:id="@+id/stagger_view_horizontal_stander"
android:title="水平标准"/>
<item android:id="@+id/stagger_view_horizontal_reverse"
android:title="水平反向标准"/>
</menu>
</item>
</menu>
MainActivity:
package com.example.recyleviewdemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.RelativeLayout;
import com.example.recyleviewdemo.adapters.GridViewAdapter;
import com.example.recyleviewdemo.adapters.ListViewAdapter;
import com.example.recyleviewdemo.beans.Datas;
import com.example.recyleviewdemo.beans.ItemBean;
import java.util.ArrayList;
import java.util.List;
/*关于RecyclerView的步骤:
第一步:当有数据,可以从本地有,可以从网络来,可以采集得到,这种实际情况实际获取。
第二步:找到控件,对吧!findViewById(xxxx),或者new出来,对于新手同学来说,这种方式使用得比较少。
第三步:设置布局管理器这步很重要,如果你忘记了,将不显示内容,即使你适配器有给,你数据有给。
第四步:创建适配器,把数据喂给适配器,适配器控制显示
第五步:把适配器设置给控件。
*
* */
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
private RecyclerView recyclerView;
private List<ItemBean> data;
private BaseAdapter adapter;
private SwipeRefreshLayout refreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
refreshLayout = findViewById(R.id.srl_swiperefresh);
recyclerView = findViewById(R.id.recycler_view);
//准备数据 现实开发数据有网络上获取 这里只是演示 模拟数据
initData();
//设置默认是listView的效果
showList(true,false);
//下拉刷新
handlerDownPullUpdate();
}
//下拉刷新 加一个控件
private void handlerDownPullUpdate() {
refreshLayout.setColorSchemeResources(R.color.purple_500,R.color.teal_700,R.color.design_default_color_primary);
refreshLayout.setEnabled(true);
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//执行刷新数据操作
/*
* 当我们在顶部,下拉的时候,这个方法就会被出发,但是,
* 这个方法是MainThread主线程,不可以执行耗时操作
* 一般开另一个线程去拿
* */
ItemBean itemBean = new ItemBean();
itemBean.title="我是被新添加的数据";
itemBean.icon = R.mipmap.thumb25;
data.add(0,itemBean);
//更新UI
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
refreshLayout.setRefreshing(false);
}
},2000);
}
});
}
private void initListener() {
adapter.setOnItemClickListener(new BaseAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
//这里处理点击条目的点击事件
Toast.makeText(MainActivity.this,"我是第"+position+"个条目",Toast.LENGTH_SHORT).show();
}
});
//处理上拉加载更多 instanceof主要作用就是来判断左边的对象是否是它右边对象的实例。”
if(adapter instanceof ListViewAdapter){
((ListViewAdapter)adapter).setOnRefreshListener(new ListViewAdapter.OnRefreshListener() {
@Override
public void onUpPullRefresh(final ListViewAdapter.LoaderMoreHolder loaderMoreHolder) {
//更新UI
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//加载更多
Random random = new Random();
if(random.nextInt() %2 == 0){
ItemBean itemBean = new ItemBean();
itemBean.title="我是被新添加的数据";
itemBean.icon = R.mipmap.thumb25;
data.add(itemBean);
//1.停止刷新,2.更新列表
adapter.notifyDataSetChanged();
loaderMoreHolder.update(loaderMoreHolder.LOADSE_STATE_NORMAL);
}else {
loaderMoreHolder.update(loaderMoreHolder.LOADSE_STATE_RELOAD);
}
}
},2000);
}
});
}
}
private void initData() {
//数据对象集合
data = new ArrayList<>();
//建立模拟数据
for(int i = 0; i< Datas.icons.length; i++){
//创建数据对象
ItemBean itemBean = new ItemBean();
itemBean.icon=Datas.icons[i];
itemBean.title="我是第"+i+"个条目";
//添加入集合
data.add(itemBean);
}
}
//复写选项菜单方法
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//拿到布局文件
getMenuInflater().inflate(R.menu.menu,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
switch (itemId){
//listview
case R.id.list_view_vertical_stander://垂直标准
showList(true,false);
break;
case R.id.list_view_vertical_reverse://垂直反向
showList(true,true);
break;
case R.id.list_view_horizontal_stander://水平标准
showList(false,false);
break;
case R.id.list_view_horizontal_reverse://水平反向标准
showList(false,true);
break;
//gridView
case R.id.grid_view_vertical_stander://垂直标准
showGrid(true,false);
break;
case R.id.grid_view_vertical_reverse://垂直反向
showGrid(true,true);
break;
case R.id.grid_view_horizontal_stander://水平标准
showGrid(false,false);
break;
case R.id.grid_view_horizontal_reverse://水平反向标准
showGrid(false,true);
break;
//瀑布流
case R.id.stagger_view_vertical_stander://垂直标准
showStagger(true,false);
break;
case R.id.stagger_view_vertical_reverse://垂直反向
showStagger(true,true);
break;
case R.id.stagger_view_horizontal_stander://水平标准
showStagger(false,false);
break;
case R.id.stagger_view_horizontal_reverse://水平反向标准
showStagger(false,true);
break;
//多种条目类型
case R.id.more_type:
// 跳到一个新的Activity里面去实现
Intent intent = new Intent(this,MoreTypeActivity.class);
startActivity(intent);
break;
}
return super.onOptionsItemSelected(item);
}
/**
* 这个方法用于实现瀑布流一样的效果
*/
private void showStagger(boolean isVertical,boolean isReverse) {
//建立布局管理器 设置水平还是垂直
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,
isVertical?StaggeredGridLayoutManager.VERTICAL:StaggeredGridLayoutManager.HORIZONTAL);
//设置方向是标准还是反向
layoutManager.setReverseLayout(isReverse);
recyclerView.setLayoutManager(layoutManager);
adapter = new StaggerAdapter(data);
recyclerView.setAdapter(adapter);
//初始化监听事件
initListener();
}
/**
* 这个方法用于实现GridView一样的效果
*/
private void showGrid(boolean isVertical,boolean isReverse) {
//建立布局管理器 第一个山下问 第二个参数是列数
GridLayoutManager layoutManager = new GridLayoutManager(this,3);
//设置布局管理器来控制样式
//设置水平还是垂直
layoutManager.setOrientation(isVertical?GridLayoutManager.VERTICAL:GridLayoutManager.HORIZONTAL);
//设置方向是标准还是反向
layoutManager.setReverseLayout(isReverse);
recyclerView.setLayoutManager(layoutManager);
adapter = new GridViewAdapter(data);
recyclerView.setAdapter(adapter);
//初始化监听事件
initListener();
}
/**
* 这个方法用于实现ListView一样的效果 recyclerView的item还有一些动画效果 自己可以去看API
*/
private void showList(boolean isVertical,boolean isReverse){
//设置布局管理器,设置样式
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//设置布局管理器来控制样式
//设置水平还是垂直
layoutManager.setOrientation(isVertical?LinearLayoutManager.VERTICAL:LinearLayoutManager.HORIZONTAL);
//设置方向是标准还是反向
layoutManager.setReverseLayout(isReverse);
//创建适配器
adapter = new ListViewAdapter(data);
recyclerView.setAdapter(adapter);
//初始化监听事件
initListener();
}
}
:
实体类:
package com.example.recyleviewdemo.beans;
//演示实体类 一般私有化属性 提供get ,set 方法 这里我们简化
public class ItemBean {
public int icon;
public String title;
}
BaseAdapter:
package com.example.recyleviewdemo.adapters;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.recyleviewdemo.R;
import com.example.recyleviewdemo.beans.ItemBean;
import java.util.List;
public abstract class BaseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
protected final List<ItemBean> mData;
private OnItemClickListener mOnItemClickListener;
public BaseAdapter(List<ItemBean> mData) {
this.mData = mData;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = getSubView(parent,viewType);
return new InnerHolder(view);
}
protected abstract View getSubView(ViewGroup parent,int viewType);
/**
* 绑定holder 设置数据
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
((InnerHolder) holder).setData(mData.get(position),position);
}
/**
* 返回条目个数
* @return
*/
@Override
public int getItemCount() {
if(mData!=null){
return mData.size();
}
return 0;
}
public void setOnItemClickListener(OnItemClickListener listener){
//设置一个监听,其实就是要设置一个接口,一个回调的接口
this.mOnItemClickListener = listener;
};
/*
* 编写回调的步骤
* 1.创建这个接口
* 2.定义接口内部的方法
* 3.内部提供设置接口的方法(其实是外部实现)
* 4.接口方法的调用
* */
public interface OnItemClickListener{
// void onItemClick(AdapterView<?> parent, View view, int position, long id);
void onItemClick(int position);
}
public class InnerHolder extends RecyclerView.ViewHolder{
private ImageView icon;
private TextView title;
private int mPosition;
public InnerHolder(@NonNull View itemView) {
super(itemView);
//找到条目的控件
icon = itemView.findViewById(R.id.icon);
title = itemView.findViewById(R.id.title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mOnItemClickListener!=null){
mOnItemClickListener.onItemClick(mPosition);
}
}
});
}
/*
* 设置数据
* */
public void setData(ItemBean itemBean,int position){
this.mPosition = position;
icon.setImageResource(itemBean.icon);
title.setText(itemBean.title);
}
}
}
多种条目:
MoreTypeActivity:
public class MoreTypeActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<MoreTypeBean> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_more_type);
recyclerView = findViewById(R.id.more_type_list);
//加载数据
initData();
//布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
MoreTypeAdapter adapter = new MoreTypeAdapter(data);
recyclerView.setAdapter(adapter);
}
private void initData() {
//数据对象集合
data = new ArrayList<>();
//随机数
Random random = new Random();
//建立模拟数据
for(int i = 0; i< Datas.icons.length; i++){
//创建数据对象
MoreTypeBean moreTypeBean = new MoreTypeBean();
moreTypeBean.pic=Datas.icons[i];
moreTypeBean.type=random.nextInt(3);
//添加入集合
data.add(moreTypeBean);
}
}
}
MoreTypeAdapter:
public class MoreTypeAdapter extends RecyclerView.Adapter {
//定义三个标识 因为有三种类型的itemView
public static final int TYPE_FULL_IMAGE = 0;
public static final int TYPE_LEFT_IMAGE = 1;
public static final int TYPE_THREE_IMAGE = 2;
private final List<MoreTypeBean> data;
public MoreTypeAdapter(List<MoreTypeBean> list) {
this.data = list;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
//TOOD:根据类型,返回对应界面
if(viewType == TYPE_FULL_IMAGE){
view = View.inflate(parent.getContext(), R.layout.item_type_full_image,null);
return new FullImageHolder(view);
}else if(viewType == TYPE_LEFT_IMAGE){
view = View.inflate(parent.getContext(), R.layout.item_type_left,null);
return new LeftImageHolder(view);
}else {
view = View.inflate(parent.getContext(), R.layout.item_type_three,null);
return new ThreeImageHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
//不要设置数据了
}
@Override
public int getItemCount() {
if(data !=null){
return data.size();
}
return 0;
}
//复写一个方法,根据条目来返回类型
@Override
public int getItemViewType(int position) {
MoreTypeBean moreTypeBean = data.get(position);
if(moreTypeBean.type == 0){
return TYPE_FULL_IMAGE;
}else if(moreTypeBean.type == 1){
return TYPE_LEFT_IMAGE;
}else {
return TYPE_THREE_IMAGE;
}
}
private class FullImageHolder extends RecyclerView.ViewHolder{
public FullImageHolder(@NonNull View itemView) {
super(itemView);
}
}
private class LeftImageHolder extends RecyclerView.ViewHolder{
public LeftImageHolder(@NonNull View itemView) {
super(itemView);
}
}
private class ThreeImageHolder extends RecyclerView.ViewHolder{
public ThreeImageHolder(@NonNull View itemView) {
super(itemView);
}
}
}