1、Listview:列表控件,使用的时候高度和宽度最好是match-parent,此外,代码中使用还需要结合适配器。
2、ListView的使用及优化:(1) 使用ConvertView重用组件,即拖动时被遮住、看不见的控件,重用它,而非每次创建一个新的对象。当ListView第一次加载的时候,前面的数据ConvertView肯定是为null,所以我们在使用ConvertView对象的时候,先要判断是否为空,为空则从布局文件中解析一个新的view对象;不为空则直接拿来使用。(2)使用ConvertView.setTag()方法,每一次给布局文件中的控件设置值时,都需要调用findById(id)方法,重复查找会浪费时间,所以我们可以把控件的地址保存到一个对象中,再把这个对象保存在ConvertView中,下次对控件进行设值的时候,直接通过这个对象修改即可。(3)使用分页查询(PullToRefresh),使用AsyncTask(异步任务)加载数据,最少要重写以下这两个方法:doInBackground(后台执行)、onPostExecute(在doInBackground方法执行结束之后再运行,并且运行在UI线程当中 可以对UI空间进行设置)。优化的过程中需要使用LayoutInflater(布局解析器),用来把layout布局文件解析成一个View对象,不可以new,需要使用系统服务获得:inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE),下面有一个例子
listview_item.xml里的代码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/iv_listviewitem_image" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="3" android:padding="10dp" android:scaleType="fitXY" android:src="@drawable/book1" /> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="6" android:orientation="vertical" android:padding="10dp" > <TextView android:id="@+id/tv_listviewitme_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="狂人摄影日记" android:textColor="@color/red" android:textSize="20sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text="书本作者:" android:textColor="@color/black" /> <TextView android:id="@+id/tv_listviewitme_author" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:text="阿刘" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text="书本价格:" android:textColor="@color/black" /> <TextView android:id="@+id/tv_listviewitme_price" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:text="$123" android:textColor="@color/black" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text=" 出版社:" android:textColor="@color/black" /> <TextView android:id="@+id/tv_listviewitme_publish" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:text="电子出版社" android:textColor="@color/black" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text="书本简介:" android:textColor="@color/black" /> <TextView android:id="@+id/tv_listviewitme_remark" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:ellipsize="end" android:maxLines="2" android:text="很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天很冷的一个冬天" android:textColor="@color/black" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="20dp" android:orientation="horizontal" > <ImageButton android:id="@+id/bt_listviewitme_btn1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_weight="1" android:src="@drawable/btn_shopping" /> <ImageButton android:id="@+id/bt_listviewitme_btn2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_weight="1" android:src="@drawable/btn_accounts" /> </LinearLayout> </LinearLayout> </LinearLayout>
activity_main.xml里的代码如下:
<?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="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.handmark.pulltorefresh.library.PullToRefreshListView android:layout_width="match_parent" android:id="@+id/lv_main_bookList" android:layout_height="match_parent" /> </LinearLayout>
BookDao里的代码如下(用以提供数据):
public class BookDao { private int[] bookImages = new int[] { R.drawable.book1, R.drawable.book2, R.drawable.book3, R.drawable.book4, R.drawable.book5, R.drawable.book6, R.drawable.book7, R.drawable.book8, R.drawable.book9, R.drawable.book10 }; public List<Book> list(int page) { List<Book> list = new ArrayList<Book>(); int rows=10; for (int i = (page-1)*rows; i < page*rows; i++) { Book b = new Book(); b.setId(i); b.setTitle("t" + i); b.setAuthor("a" + i); b.setPrice(0.0f + i); b.setPublish("p" + i); b.setRemark("r" + i); // 真实开发图片应该是从网络获取,而非本地获得 b.setImage(bookImages[i % bookImages.length]); list.add(b); } return list; }}
MainActivity里的代码如下:
public class MainActivity extends AppCompatActivity { private List<Book> data = new ArrayList<>();//数据源 private PullToRefreshListView lv_main_bookList;//PullToRefreshListView控件 private MyBaseAdapter adapter;//自定义的适配器 private int page = 1;//第一页数据 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_main_bookList = findViewById(R.id.lv_main_bookList);//根据ID找到PullToRefreshListView控件 lv_main_bookList.setMode(PullToRefreshBase.Mode.PULL_FROM_END);//设为刷新模式为上拉 lv_main_bookList.getLoadingLayoutProxy().setPullLabel("上拉刷新...");//刚拉时,显示的提示 lv_main_bookList.getLoadingLayoutProxy().setRefreshingLabel("正在载入...");//刷新时 lv_main_bookList.getLoadingLayoutProxy().setReleaseLabel("放开刷新...");//拉到一定距离时,显示的提示 //刷新时的监听事件 lv_main_bookList.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() { @Override public void onRefresh(PullToRefreshBase<ListView> refreshView) { new MyAsyncTask().execute(); } }); data = new BookDao().list(page);//初始化第一页数据 adapter = new MyBaseAdapter((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)); lv_main_bookList.setAdapter(adapter); } public class MyAsyncTask extends AsyncTask { @Override protected Object doInBackground(Object[] objects) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } data.addAll(new BookDao().list(++page)); return null; } @Override protected void onPostExecute(Object o) { super.onPostExecute(o); adapter.notifyDataSetChanged();// 通知适配器数据已改变 lv_main_bookList.onRefreshComplete();// 通知控件数据已经加载完毕 } } //自定义的适配器 public class MyBaseAdapter extends BaseAdapter { public class viewHolder { ImageView iv_listviewitem_image; TextView tv_listviewitme_title; TextView tv_listviewitme_author; TextView tv_listviewitme_price; TextView tv_listviewitme_publish; TextView tv_listviewitme_remark; } private LayoutInflater inflater;//布局解析器 //自定义适配器的构造方法 public MyBaseAdapter(LayoutInflater layoutInflater) { this.inflater = layoutInflater; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int i) { return data.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View convertView, ViewGroup parent) {// 1、将项资源解析成可见的视图 View v = convertView; if (v == null) { viewHolder vh = new viewHolder(); v = inflater.inflate(R.layout.listview_item, null); vh.iv_listviewitem_image = v.findViewById(R.id.iv_listviewitem_image); vh.tv_listviewitme_author = v.findViewById(R.id.tv_listviewitme_author); vh.tv_listviewitme_price = v.findViewById(R.id.tv_listviewitme_price); vh.tv_listviewitme_publish = v.findViewById(R.id.tv_listviewitme_publish); vh.tv_listviewitme_remark = v.findViewById(R.id.tv_listviewitme_remark); vh.tv_listviewitme_title = v.findViewById(R.id.tv_listviewitme_title); v.setTag(vh); }// 2、从视图中获取控件(这些控件都是没有值) viewHolder viewHolder = (MyBaseAdapter.viewHolder) v.getTag();// 3、获取当前需要展示的数据,将值封装进控件中 Book book = data.get(i); viewHolder.tv_listviewitme_title.setText(book.getTitle()); viewHolder.tv_listviewitme_remark.setText(book.getRemark()); viewHolder.tv_listviewitme_publish.setText(book.getPublish()); viewHolder.iv_listviewitem_image.setImageResource(book.getImage()); viewHolder.tv_listviewitme_price.setText(book.getPrice() + ""); viewHolder.tv_listviewitme_author.setText(book.getAuthor()); return v; } }