为了解决ListView运行效率低,不能实现横向滚动的确定,Android在V7的包中新增了RecyclerView控件,RecyclerView除了可以轻松实现ListView的功能外还优化了ListView的不足之处以及能实现横向滚动和瀑布流。
为了方便理解,先用RecyclerView来实现ListView的功能:
很丑是不是? 没关系,今天我们的主角是瀑布流。这个就先将就一下,我总结了一下实现使用RecyclerView的一般步骤(这个例子使用的是android Studio平台):
1、RecyclerView是新增的控件,为了兼容低版本需要在buid.gredle中添加对应的库。
compile 'com.android.support:recyclerview-v7:24.2.1'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
testCompile 'junit:junit:4.12'
}
2、和ListView一样,需要提供一个数据源。
3、在布局文件中添加一个RecyclerView控件。
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
4、在Activity中关联控件并且进行一些设置。
RecyclerView一共有三个Manager类:LinearLayoutManager,StaggeredGridLayoutManager, GridLayoutManager。分别对应RecyclerView的三种模式:线性流布局,瀑布流布局,网格流布局。
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);//1、关联UI
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);//2、实例化理类
recyclerView.setLayoutManager(linearLayoutManager);//3、设置管理类
RecyclerAdapter adapter = new RecyclerAdapter(r_Image, r_Name);//4、实例化适配器
recyclerView.setAdapter(adapter);//5、设置适配器
5、为适配器创建一个布局文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal">
<ImageView
android:layout_width="120sp"
android:layout_height="120sp"
app:srcCompat="@drawable/aa"
android:id="@+id/imageView" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="22dp"
android:paddingLeft="10sp"
android:textSize="16sp"
android:id="@+id/textView" />
</LinearLayout>
6、创建一个适配器RecyclerView.Adapter的子类并且重写三个必需重写的方法:
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //创建Holder实例并且返回,Holder用来缓存实例优化响应效率。
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_ayout, parent, false);
final ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
//构造函数,传递两个参数为RecyclerView的数据源数据,这里用两个数组来提供数据
public RecyclerAdapter(int[] r_Image, String[] r_Name) {
this.r_Image = r_Image;
this.r_Name = r_Name;
}
@Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {
//更新UI
holder.imageView.setImageResource(r_Image[position]);
holder.textView.setText(r_Name[position]);
}
@Override
public int getItemCount() {//返回子项个数
return r_Image.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ViewHolder(View itemView) {//关联UI控件
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
上面就实现了线性流布局的垂直滚动,如果需要改成横向滚动只需要在上面步骤4中,在为RecyclerView设置布局方式之前将布局管理器设置成横向就可以:
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//设置滚动方向
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);//2、实例化理管理类
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//设置滚动方向
recyclerView.setLayoutManager(linearLayoutManager);//3、设置管理类
对比ListView来理解,就会发现RecyclerView比ListView更加简单了。使用RecyclerView完成RecyclerView的线性流布局后,要实现瀑布流布局非常简单,严格来说只要修改管理类就可以,但是为了UI更加美观,一般来来说我们都会修改一下UI的布局。需要修改的两个参数:
1、将LinearLayoutManager管理类更换成StaggeredGridLayoutManager类
StaggeredGridLayoutManager类有两个参数,第一个为int型,设置瀑布流的列数。第二个指定布局的排列方向,我们设置为纵向排列。
StaggeredGridLayoutManager linearLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
2、修改UI参数.
到这里就可以实现瀑布流,但是为了瀑布流的效果明显,我还将提供数据的数组修改成了长短不一。
(完全没有意义的一些数据,在代码中随便拷贝的)
R.drawable.hh, R.drawable.ii, R.drawable.jj};
private String r_Name[] = {"1 StaggeredGridLayoutManager linearLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);" +
" recyclerView.setLayoutManager(linearLayoutManage", "2setLayoutManager(linearLayoutMa", "3setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa", "4setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa", "5setLayoutManager(linearLayoutMa", "6setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa", "7setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa",
"8setLayoutManager(linearLayoutMa", "9setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa", "10setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa"};
效果图:
瀑布流,图片配上英文说明,倍有B格是不是!!!
完整源码分割线
两个例子的代码非常相似,这里只贴瀑布流的实现源码:
buid.gredle修改后:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.1"
defaultConfig {
applicationId "com.example.administrator.class_recyclerviewtest"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
testCompile 'junit:junit:4.12'
}
Activity类:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private int r_Image[] = {R.drawable.aa, R.drawable.bb, R.drawable.cc,
R.drawable.dd, R.drawable.ee, R.drawable.ff, R.drawable.gg,
R.drawable.hh, R.drawable.ii, R.drawable.jj};
private String r_Name[] = {"1 StaggeredGridLayoutManager linea anager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);" +
" recyclerView.setLayoutManager(linear tManage", "2setLayoutManager(linearLayoutMa", "3setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa",
"4setLayoutManager(linearyoutManager(linearLayoutMasetLayoutManager(linearLayoutMa", "5setLayoutManager(linearLayoutMa",
"6setLa rLayoutMasetLayoutManager(linearLayo youtManager(linearLayoutMasetLayoutManager(linearLayoutMa", "7setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa",
"8setLayoutManager(linearLayoutMa", "9setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa", "10setLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMasetLayoutManager(linearLayoutMa"};
private List<List<String>> r_list = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);//1、关联UI
// LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);//2、实例化理类
// linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//设置滚动方向
StaggeredGridLayoutManager linearLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);//3、设置管理类
RecyclerAdapter adapter = new RecyclerAdapter(r_Image, r_Name);//4、实例化适配器
recyclerView.setAdapter(adapter);//5、设置适配器
}
}
自定义适配器类:
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
//import android.R;
/**
* Created by Administrator on 2016/12/12 0012.
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private int[] r_Image;
private String[] r_Name;
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_ayout, parent, false);
final ViewHolder viewHolder = new ViewHolder(view);
viewHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override//点击事件监听
public void onClick(View view) {
int position = viewHolder.getAdapterPosition();
Toast.makeText(view.getContext(), r_Name[position], Toast.LENGTH_SHORT).show();
}
});
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override//点击事件监听
public void onClick(View view) {
int position = viewHolder.getAdapterPosition();
Toast.makeText(view.getContext(), r_Name[position] + "Imange", Toast.LENGTH_SHORT).show();
}
});
return viewHolder;
}
public RecyclerAdapter(int[] r_Image, String[] r_Name) {
this.r_Image = r_Image;
this.r_Name = r_Name;
}
@Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {
holder.imageView.setImageResource(r_Image[position]);
holder.textView.setText(r_Name[position]);
}
@Override
public int getItemCount() {
return r_Image.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ViewHolder(View itemView) {//关联UI控件
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
UI布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administrator.class_recyclerviewtest.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
RecyclerView适配器布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<ImageView
android:layout_width="120sp"
android:layout_height="120sp"
app:srcCompat="@drawable/aa"
android:id="@+id/imageView" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="22dp"
android:paddingLeft="10sp"
android:textSize="16sp"
android:id="@+id/textView" />
</LinearLayout>