优化步骤麻烦:①复用convertView ②新建一个Viewholder来保存UI组件
可是说是面向View编程的,它的扩展性也不好,只能实现纵向滚动的效果,如果我们想在ListView中实现横向滚动是做不到的;
因此谷歌提供了一个功能更强大的组件——RecyclerView。它可以说是一个增强版的listView,不仅可以实现和ListView中相同的效果,还优化了listView中存在的各种不足。目前谷歌官方推荐使用RecyclerView。那么本篇文章就来详细讲解一下RecyclerView。
由于RecyclerView是新增的控件,为了能让它在所有的版本中都能使用,谷歌还是把RecyclerView放到了support库中,要想使用RecyclerView,首先需要在build.gradle中添加相应的依赖库才能使用:
compile 'com.android.support:recyclerview-v7:24.1.0'
添加完成要Sync Now进行同步。
然后在布局文件上添加如下代码:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/recycle_rv"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
由于RecyclerView不是内置在SDK中的,所以需要把完整的包的路径写出来;
接下来写适配器:
package com.example.forget.recyle;
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.ListView;
import android.widget.TextView;
import java.util.List;
import java.util.Map;
/**
* Created by Forget on 2017/1/7.
*/
public class MyRecycleViewAdapter extends RecyclerView.Adapter<MyRecycleViewAdapter.ViewHolder> {
private List<Map<String, Object>> list;
public MyRecycleViewAdapter(List<Map<String, Object>> list) {
this.list = list;
}
/**
* @param parent 此参数是外类中通过setlayoutmanager传递进来的布局
* @param viewType 代表view的类型
* @return 返回一个ViewHolder容器
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item
, parent, false);
// 将加载的布局通过ViewHoder的构造方法传递进来
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
/**
* @param holder 此处的ViewHolder就是recyclerView的每一项
* @param position 代表recyclerView的每一个位置
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.hero_iamge.setImageResource((Integer) list.get(position).get("image"));
holder.hero_desc.setText((CharSequence) list.get(position).get("desc"));
}
@Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView hero_iamge;
TextView hero_desc;
public ViewHolder(View itemView) {
super(itemView);
hero_iamge = (ImageView) itemView.findViewById(R.id.hero_iv);
hero_desc = (TextView) itemView.findViewById(R.id.hero_desc);
}
}
}
RecyclerView是面向viewHolder编程的,上面的代码首先定义了一个内部类ViewHolder,ViewHolder需要继承RecyclerView.ViewHolder,我们定义的ViewHolder的构造函数需要传入一个View参数,这个参数就是每一个条目的最外边的布局容器,我们可以通过findviewByid获取布局中的UI组件;
自定义的adapter的构造函数用于初始化数据源,自定义的adapter需要实现onCreateViewHolder(),onBindViewHolder()和getItemcount()三个方法。
onCreateViewHolder()方法用于创建ViewHolder实例,将布局文件加载出来,通过ViewHolder的构造函数传入此View,完成ViewHolder的的构建,并返回此ViewHolder
onBindViewHolder()该方法是对于recyclerView的子项进行赋值
getItemcount()表示RecyclerView一共有多少项
适配器的工作完成了,接下来修改Activity中的代码:
package com.example.forget.recyle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.LinearLayout;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Map<String, Object>> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
LinearLayoutManager llm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(llm);
MyRecycleViewAdapter adapter = new MyRecycleViewAdapter(list);
recyclerView.setAdapter(adapter);
}
private void initData() {
list = new ArrayList<>();
String [] desc=new String[]{"你看到我的小熊了吗?","想和我玩儿么?可别怪我的尾巴无情哟",
"规则,就是用来打破的","我可没有刮胡子的闲工夫",
"断剑重铸之日,骑士归来之时","我要吃掉他们!"};
int [] iamges=new int[]{R.mipmap.anni,R.mipmap.huli,R.mipmap.jinkesi,R.mipmap.nanqiang,R.mipmap.ruiwen,
R.mipmap.xiaoyu};
for (int i = 0; i <desc.length ; i++) {
Map<String,Object> map=new HashMap<>();
map.put("image",iamges[i]);
map.put("desc",desc[i]);
list.add(map);
}
}
private void initView() {
recyclerView = (RecyclerView) findViewById(R.id.recycle_rv);
}
}
这里比较重要的方法是 recyclerView.setLayoutManager(llm),这里表示指定recyclerView布局方式,可以实现和listView类似的效果:
实现横向滚动:
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.HORIZONTAL);
给布局管理器指定排列方式即可,效果如下:
RecyclerView的事件处理:
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView hero_iamge;
TextView hero_desc;
View hero;
public ViewHolder(View itemView) {
super(itemView);
hero=itemView;
hero_iamge = (ImageView) itemView.findViewById(R.id.hero_iv);
hero_desc = (TextView) itemView.findViewById(R.id.hero_desc);
}
}
在onCreateViewHolder中可以对整个子项设置事件,也可以对单个UI设置事件:
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item
, parent, false);
// 将加载的布局通过ViewHoder的构造方法传递进来
final ViewHolder viewHolder = new ViewHolder(view);
viewHolder.hero.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int postion=viewHolder.getAdapterPosition();
Toast.makeText(parent.getContext(), ""+list.get(postion).get("desc").toString(), Toast.LENGTH_SHORT).show();
}
});
return viewHolder;
}
效果如下:
好啦,今天就简单介绍这些吧,日后再说更加炫酷的功能。