Andriod ListView

xiaoxiao2021-02-28  91

一、最简单的ListView

在布局文件里面,只需要定义一个ListView对象

<ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/list_view"></ListView>

在mainAcitivity里面:

给出数据,创建合适的适配器。simple_expandable_list_item_1是Andriod系统自带的ListView,每一行的TextView只显示一行的内容。

private String[] data = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_expandable_list_item_1, data); ListView listView = (ListView)findViewById(R.id.list_view); listView.setAdapter(arrayAdapter);

二、通过自定义控件实现的ListView

要实现这种效果,首先自定义每一行的布局

<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/number_image"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/number_name" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp"/>

仿照最基本的用法,即给出某一类型的数据,建立适当的适配器。

所以首先建立一个自定义的类Number,把要显示在TextView的内容和图片的ID作为两个成员变量。

public class Number { public Number(String name, int id){ this.name = name; this.id = id; } public String getName(){ return name; } public int getId(){ return id; } private String name; private int id; }

接下来要创建一个类——Number类型的适配器,继承于ArrayAdapter<>。

public class NumberAdapter extends ArrayAdapter<Number> { private int id; public NumberAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<Number> objects) { super(context, resource, objects); id = resource; } //重写getView方法,使每个子项被滚动到屏幕时都能被调用 @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { //据索引获取集合中的一个对象   Number number = getItem(position); //从Context中,获得一个布局填充器,并且使用这个填充器来把xml布局文件转为View对象 View view = LayoutInflater.from(getContext()).inflate(id, parent, false); //初始化ImageView对象和TextView对象  ImageView numberImage = view.findViewById(R.id.number_image); TextView numberName = view.findViewById(R.id.number_name); //设置图片和文本内容  numberImage.setImageResource(number.getId()); numberName.setText(number.getName()); return view; } }  在mainActivity里面

public class MainActivity extends AppCompatActivity { private List<Number> numbers = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initNumber();//自定义了一个函数,用于加载数据 NumberAdapter numberArrayAdapter = new NumberAdapter(MainActivity.this,R.layout.number_item, numbers); ListView listView = (ListView)findViewById(R.id.list_view); listView.setAdapter(numberArrayAdapter); } }

private void initNumber(){ Number one = new Number("1",R.drawable.small_707); Number two = new Number("2",R.drawable.small_708); Number three = new Number("3",R.drawable.small_709); Number four = new Number("4",R.drawable.small_710); Number five = new Number("5",R.drawable.small_711); Number six = new Number("6",R.drawable.small_712); Number seven = new Number("7",R.drawable.small_713); Number eight = new Number("8",R.drawable.small_714); Number nine = new Number("9",R.drawable.small_715); numbers.add(one); numbers.add(two); numbers.add(three); numbers.add(four); numbers.add(five); numbers.add(six); numbers.add(seven); numbers.add(eight); numbers.add(nine); }

三、对自定义适配器NumberAdapter的优化

       1.0

       在上面的代码中,每次调用view都要重新加载,我们可以通过判断view是否存在直接调用已经存在的view。即如果convertView为null,就用LayoutInflatr去加载布局,如果

不为null就直接对convertView进行重用。

(关于convertView是什么,参考: http://blog.csdn.net/bill_ming/article/details/8817172)

       这时候虽然避免了 布局的重复加载,在if else 外每次都对ImageView和TextView进行控件的实例化。

@NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Number number = getItem(position); //不需要重新加载已存在的布局 View view; if (convertView == null){ view = LayoutInflater.from(getContext()).inflate(id, parent, false); }else { view = convertView; } ImageView numberImage = (ImageView)view.findViewById(R.id.number_image); TextView numberName = (TextView)view.findViewById(R.id.number_name); numberImage.setImageResource(number.getId()); numberName.setText(number.getName()); return view; }

      2.0

    

public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Number number = getItem(position); View view; ViewHolder viewHolder; if (convertView == null){ view = LayoutInflater.from(getContext()).inflate(id, parent, false);//加载布局 viewHolder = new ViewHolder(); viewHolder.imageNumber = view.findViewById(R.id.number_image); viewHolder.nameNumber = view.findViewById(R.id.number_name); view.setTag(viewHolder);//将viewHolder储存在view中 }else { view = convertView; viewHolder = (ViewHolder) view.getTag();//重新获取viewHolder } viewHolder.imageNumber.setImageResource(number.getId()); viewHolder.nameNumber.setText(number.getName()); return view; } class ViewHolder { ImageView imageNumber; TextView nameNumber; }      新增了一个内部类ViewHolder,用于对控件进行缓存。当convertView为null的时候,创建新的ViewHolder对象,并将控件的实例储存在view里面。当convertView不为null的时候,就调用getTag()重新获取ViewHolder。就避免了每次通过findviewbyid的方法获取控件实例了。

四、添加响应事件

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Number number = numbers.get(i); Toast.makeText(MainActivity.this, number.getName(), Toast.LENGTH_SHORT).show(); } });

转载请注明原文地址: https://www.6miu.com/read-31524.html

最新回复(0)