ListView :当我们需要有大量的数据信息进行显示时,这时就需要用到ListView。那么如何使用它呢?
简单使用:
1、在布局文件中创建ListView控件并设置相关属性id如:easy_list_view。
2、在activity中创建Adapter,Listview和一个数组对象。
private Integer[] data = new Integer[200];
for (int i = 0;i<200;i++) { data[i] = i; } ArrayAdapter<Integer> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data); ListView listView = (ListView) findViewById(R.id.easy_list_view); listView.setAdapter(adapter);
总结:这样的listView特别简单只是单纯的用了sdk原生的东西。但我们一般用到的数据都不会是一组数据就一个信息,肯定是有图有文字甚至很多复杂的控件。所以下面的是重点学习的。
自定义ListView:
我把我们接下来要作的事罗列一下:
1、创建自定义布局(list一行的布局)。
2、创建创建数据Bean类(这里是我的一个自称:可以理解为一个数据类)。
public class Fruit { Fruit(String name, int imageId) { this.name = name; this.imageId = imageId; } public String getName() { return name; } public int getImageId() { return imageId; } private String name = "1"; private int imageId = R.drawable.one; }
3、自定义一个Adapter继承的Adapter看情况,我这里是Array。
/* * 继承ArrayAdapter自定义Adapter * 且是通过convertView与ViewHolder共同优化的一个自定义adapter。 * 用setTag与getTag方法达到ViewHolder的重用。 * */ public class FruitAdapter extends ArrayAdapter<Fruit> { // 此为自定义的布局 private int resourceId; // 构造方法。获取自定义布局 FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> fruits) { super(context, resource, fruits); resourceId = resource; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Fruit fruit = getItem(position);//获取当前项的fruit实例 View view; ViewHolder viewHolder; //重用 if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);//加载布局 viewHolder = new ViewHolder(); viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image); viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name); view.setTag(viewHolder); }else{ view = convertView; viewHolder = (ViewHolder) view.getTag(); } assert fruit != null; viewHolder.fruitImage.setImageResource(fruit.getImageId()); viewHolder.fruitName .setText(fruit.getName()); return view; } class ViewHolder{ ImageView fruitImage; TextView fruitName; } }
4、在activity使用它们;
public class DefineListViewActivity extends AppCompatActivity { private List<Fruit> fruitList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_define_list_view); //循环多遍历一点 for (int i = 0; i < 10; i++) initFruits(); FruitAdapter adapter = new FruitAdapter(this, R.layout.define_list_view_fruit, fruitList); ListView listView = (ListView) findViewById(R.id.define_list_view); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Fruit fruit = fruitList.get(position); Toast.makeText(DefineListViewActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show(); } }); } private void initFruits() { Fruit one = new Fruit("one", R.drawable.one); Fruit two = new Fruit("two", R.drawable.two); Fruit three = new Fruit("three", R.drawable.three); Fruit four = new Fruit("four", R.drawable.four); Fruit five = new Fruit("five", R.drawable.five); Fruit six = new Fruit("six", R.drawable.six); Fruit seven = new Fruit("seven", R.drawable.seven); fruitList.add(one); fruitList.add(two); fruitList.add(three); fruitList.add(four); fruitList.add(five); fruitList.add(six); fruitList.add(seven); } }
更强大的滚动控件RecyclerView:
相比较而言,RecyclerView的性能及功能比ListView更强大,所以现在我们更应该去学习这个控件。
1、由于这个是新加的所以这个是在support库中才有的所以需要依赖recyclerview这个库。
2、创建自定义布局:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@string/picture"
app:srcCompat="@drawable/one" />
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/textview"
android:textSize="14sp" />
</LinearLayout>
3、创建基本的数据类Fruit;
public class Fruit {
private String fruitName;
private int fruitImage;
Fruit(String fruitName,int fruitImage){
this.fruitName = fruitName;
this.fruitImage = fruitImage;
}
public String getFruitName() {
return fruitName;
}
public int getFruitImage() {
return fruitImage;
}
}
4、创建自定义Adapter注意:继承RecyclerView.Adapter<类.ViewHolder>其中ViewHolder这是个内部类且继承了RecyclerView.ViewHolder。
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
// 水果数据
private List<Fruit> fruits;
// 在构造时获取水果数据
FruitAdapter(List<Fruit> fruits) {
this.fruits = fruits;
}
// 加载布局并创建实例ViewHolder
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new ViewHolder(view);
}
// 把数据与子项绑定起来
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = fruits.get(position);
holder.fruitImage.setImageResource(fruit.getFruitImage());
holder.fruitName.setText(fruit.getFruitName());
}
// 获取数据的长度
@Override
public int getItemCount() {
return fruits.size();
}
// 创建静态的内部类ViewHolder并继承RecyclerView.ViewHolder
static class ViewHolder extends RecyclerView.ViewHolder {
TextView fruitName;
ImageView fruitImage;
ViewHolder(View itemView) {
super(itemView);
fruitName = (TextView) itemView.findViewById(R.id.item_name);
fruitImage = (ImageView) itemView.findViewById(R.id.imageView);
}
}
}
5、在Activity中显示它们,与ListView步骤差不多,只不过多了一步LinearLayoutManager
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruits=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initfruist();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
RecyclerView recyclerView = findViewById(R.id.reclyclerView);
recyclerView.setLayoutManager(linearLayoutManager);
FruitAdapter fruitAdapter = new FruitAdapter(fruits);
recyclerView.setAdapter(fruitAdapter);
}
private void initfruist() {
for (int i=0;i<200;i++) {
fruits.add(new Fruit("one", R.drawable.one));
fruits.add(new Fruit("two", R.drawable.two));
fruits.add(new Fruit("three", R.drawable.three));
fruits.add(new Fruit("four", R.drawable.four));
fruits.add(new Fruit("five", R.drawable.five));
fruits.add(new Fruit("six", R.drawable.six));
fruits.add(new Fruit("seven", R.drawable.seven));
}
}
}
其实RecycleView还是挺简单的逻辑上易于理解,只要上代码两三遍基本就也就稍微会用了。当然垃圾而又神奇的RecyclerView让我搞了一个下午,为什么?
我和别人的步骤一模一样,但是我的item布局就算把LinearLayout的Layout_width和layout_height改成wrap_content但是依旧是会看见我的子项永远占一个屏幕。原因我无意中发现,当我把长长的布局名称重命名成原来名字长度的一半时,运行发现它居然好了。我去。。。。顿时一万批草尼马奔腾而过。。。唉千万不要放弃自己的直觉。