最近课程大作业,要求做出一个物联网信息采集系统,需要一个android app。
listview最初想实现类似微信服务号的推送的消息那种,最后的效果如下
具体实现主要两个地方
- 自定义apapter
- 动态更新listview
- 首先定义listview对应元素的xml文件
每一个listview包含两个textview和一个view(做分隔符)两个textview分别存放title description。
<?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="match_parent"
android:orientation="vertical"
android:background="@color/white">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id = "@+id/title"
style = "@style/titleText"
android:clickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id = "@+id/description"
style="@style/descriptionText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<View
android:id = "@+id/divider"
android:layout_height="32dp"
android:layout_width="match_parent"
android:background="@color/light_grey"
/>
`</LinearLayout>
- 自定义adpater 规定渲染方法
public class MessageAdapter extends ArrayAdapter{
private final int resoureId;
private Context context;
private List<Message> objects;
public MessageAdapter(Context context, int textviewResourceId, List<Message>objects){
//context -> activity instance
// textViewResourId listView 元素对应的xml文件
// objects 需要渲染的对象集 每一个对象被渲染到list view的一个元素中
super(context, textviewResourceId, objects);
resoureId = textviewResourceId;
this.context = context;
this.objects = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
//定义渲染方法
Message message = (Message) getItem(position);
//使用 LayoutInflater将 布局文件解析为view 这里比较疑惑的是 同一个resourceid 是怎么得到不同的子元素的
//将xml文件转为view对象
View view = LayoutInflater.from(getContext()).inflate(resoureId, null);
//找到xml中title部分
TextView title = view.findViewById(R.id.title);
TextView description = view.findViewById(R.id.description);
title.setText(message.getTitle());
description.setText(message.getDescription());
return view;
}
public void add(Message message){
//添加消息方法
objects.add(message);
//通知数据改变 界面view会同步改变数据
notifyDataSetChanged();
}
}
- message_list
list view 对应activity 直接继承ListActivity 在onCreate方法中设置adpater
注意如果在子线程中定义更新list view的时机,具体修改 即调用notifyDataSetChanged 需要在UI线程 ,可通过runOnUiThread实现,也有其它的方法。
MessageAdapter myadapter = new MessageAdapter(message_list.this, R.layout.message_item, messageDao.getLists(), message_list.this);
setListAdapter(myadapter);
Runnable add = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3 * 1000);
}catch (Exception e){
int b = 1;
}
//messageDao.getLists().add(new Message("new", "new", "2019-06-12 11:40:44"));
//myadapter.notifyDataSetChanged();
runOnUiThread(new Runnable() {
@Override
public void run() {
myadapter.add(new Message("new", "new", "2019-06-12 11:40:44"));
}
});
}
};
Thread add_thread = new Thread(add);
add_thread.start();