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但是依旧是会看见我的子项永远占一个屏幕。原因我无意中发现,当我把长长的布局名称重命名成原来名字长度的一半时,运行发现它居然好了。我去。。。。顿时一万批草尼马奔腾而过。。。唉千万不要放弃自己的直觉。