由于手机屏幕空间比较有限,当我们利用手机浏览信息时,能够一次性在屏幕上显示的内容很少,往往需要用户通过滑动手指的方式将屏幕外的数据滚动到屏幕内,与此同时原来屏幕上原有的数据则会滚动出屏幕。此情形我们可类比我们在查看QQ聊天记录与翻阅微博最新消息等。ListView控件可以说很好的解决了上述问题,他以列表的形式展现具体内容,并且能够根据数据的长度自适应显示,还能处理用户选择单击等操作。
如上图所示,为新闻客户端的界面,由于新闻数量较多,因而在布局中,采用了ListView控件。首先,在主界面即acticity_main.xml中,加入ListView控件。具体代码如下所示。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.jikexueyuan.news.MainActivity"> <ListView android:id="@+id/lvNews" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>接着,在布局文件夹中新建一个news_item.xml布局作为ListView每个控件的布局。也就是说,你打算在ListView控件中让其中的条目显示什么内容,则该布局就是你想显示出来的。新闻客户端的具体代码如下。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/ivpic" android:layout_width="42dp" android:layout_height="42dp" android:src="@mipmap/ic_launcher" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="title" android:textSize="18sp" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/ivpic" android:layout_toEndOf="@+id/ivpic" /> <TextView android:id="@+id/tvDesc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tvTitle" android:layout_toRightOf="@+id/ivpic" android:text="desc"/> <TextView android:id="@+id/tvTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="time" android:textSize="10sp"/> </RelativeLayout>可以看到,我在该布局下放置了一个图片控件,三个文本控件。此时我们可以新建一个新闻类,作为初始化数据并把数据传给ListView的桥梁。具体如下所示。
package com.jikexueyuan.news.com.jikexueyuan.news.model; /** * Created by ACER on 2017/3/11. */ public class News { private String title; private String desc; private String time; private String content_url; private String pic_url; public News(String title,String desc,String time,String content_url,String pic_url){ setTime(title); setDesc(desc); setTime(time); setContent_url(content_url); setPic_url(pic_url); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getContent_url() { return content_url; } public void setContent_url(String content_url) { this.content_url = content_url; } public String getPic_url() { return pic_url; } public void setPic_url(String pic_url) { this.pic_url = pic_url; } }
在定义完News类后,我们需要借助适配器来将数据传给ListView。Android中提供了很多适配器,在这个项目中,我用的是ArrayAdapter。具体代码如下。
package com.jikexueyuan.news.com.jikexueyuan.news.dapter; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.jikexueyuan.news.R; import com.jikexueyuan.news.com.jikexueyuan.news.model.News; import com.jikexueyuan.news.com.jikexueyuan.news.utils.HttpUtils; import java.util.List; public class NewsAdapter extends ArrayAdapter<News> { private int resourceId; public NewsAdapter(Context context,int textViewResourceTd,List<News>objects){ super(context,textViewResourceTd,objects); resourceId=textViewResourceTd; } @Override public View getView(int position, View converView, ViewGroup parent){ News news=getItem(position); View view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false); TextView tvTitle=(TextView) view.findViewById(R.id.tvTitle); TextView tvDesc=(TextView) view.findViewById(R.id.tvDesc); TextView tvTime=(TextView) view.findViewById(R.id.tvTime); ImageView ivPic=(ImageView)view.findViewById(R.id.ivpic); tvTitle.setText(news.getTitle()); tvDesc.setText(news.getDesc()); tvTime.setText(news.getTime()); String pic_url=news.getPic_url(); HttpUtils.setPicBitmap(ivPic,pic_url); return view; } }在这里要说明下,context 表示应用程序上下文,textViewResourceId 表示布局文件资源,object表示数据源。
NewsAdapter重写了父类的一组构造函数,用于将上下文、ListView子项布局的id和数据都传递进来。另外又重写了getview()方法,这个方法在每个子项被滚到屏幕内的时候会被调用。在getView()方法中,首先通过getItem()方法得到当前项的News实例,如然后使用LayoutInflater来为这个子项加载我们传入的布局。接着调用View的findViewById()方法获取到TextView的实例,注意,由于在该项目中,图片的位置我是通过网络来获取的,并不是直接存放与项目中,所以,不能用setImageResource()方法来获取图片。因为图片是通过网络来访问获取到的,所以此刻,我们可以通过android网络技术来获取图片并将其加载进来。具体方法如下。
public static void setPicBitmap(final ImageView ivPic,final String pic_url){ new Thread(new Runnable() { @Override public void run() { try { HttpURLConnection conn=(HttpURLConnection) new URL(pic_url).openConnection(); conn.connect(); InputStream is=conn.getInputStream(); Bitmap bitmap= BitmapFactory.decodeStream(is); ivPic.setImageBitmap(bitmap); is.close(); }catch (Exception e){ e.printStackTrace(); } } }).start(); }该方法有两个参数,第一个参数为ImageView类型的对象,表示要填充的是那一个图片,另外一个为该图片的网址。接着就是开启一个新的线程,接着用HttpURLconnection来读取网络数据,接着调用.connection()方法与远端的服务器进行连接,接着用geyInpuStream()方法获取当前的输入流。接着可以调用BitmapFactory的decodeStream方法来返回一个Bitmap对象,并调用.setImageBitmap方法设置图片。
在完成上述工作后,我们只是实现了LIstView列表数据的填充,并不能实现跳转,为了解决这个问题,我们可以用ListView的响应单击事件的方法来实现。
ListView的响应单击事件是通过OnItemClickListener()方法为ListView注册条目单击事件进行监听与处理。在这个项目中我们为ListView添加相应的点击事件是在主函数中实现OnItemClickListener这个接口,并添加其未实现的方法。具体如下
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { News news=newsList.get(position); Intent intent=new Intent(this,BrowseNewsActivity.class); intent.putExtra("content_url",news.getContent_url()); startActivity(intent); }在该方法中,各个参数的含义如下:
parent是指父View,即ListView
view是当前ListView条目的View,通过它可以获得该条目中的各个组件
position是当前ListView条目的id。这个id根据在适配器中的写法可以自己定义
id是当前ListView条目在ListView中的相对位置
参考资料:《第一行代码》第2版 郭霖
《Android应用开发教程》刘志强主编