android listview不能刷新 adapter.notifyDataSetChanged()和setListAdapter(myAdapter)都不好用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android listview不能刷新 adapter.notifyDataSetChanged()和setListAdapter(myAdapter)都不好用相关的知识,希望对你有一定的参考价值。

public class PortraitContectPicActivity extends ListActivity
Context mContext = null;
private static final String[] PHONES_PROJECTION = new String[]
...
private ArrayList<String> mContactsName = new ArrayList<String>();

...
ListView mListView = null;
MyListAdapter myAdapter = null;
@Override
public void onCreate(Bundle savedInstanceState)
mContext = this;
mListView = this.getListView();
getPhoneContacts();

myAdapter = new MyListAdapter(this);
setListAdapter(myAdapter);
Intent intent=getIntent();
String value=intent.getStringExtra(Util.RESULT_EDIT_PROTRAIT_ID);
final String pic = value;
mListView.setOnItemClickListener(new OnItemClickListener()

@Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id)
ContentResolver c = getContentResolver();
Bitmap sourceBitmap = BitmapFactory.decodeFile(pic);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
sourceBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
byte[] avatar =os.toByteArray();
ContentValues values = new ContentValues();
Cursor cursor = c.query(ContactsContract.Contacts.CONTENT_URI, null, "DISPLAY_NAME = '" + mContactsName.get(position) + "'", null,
null);
if (cursor.moveToFirst())
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
values.put(Photo.PHOTO, avatar);
getContentResolver().update(android.provider.ContactsContract.Data.CONTENT_URI, values, " raw_contact_id=? and mimetype=?", new String[]contactId,Photo.CONTENT_ITEM_TYPE);

cursor.close();
setListAdapter(myAdapter);


);

super.onCreate(savedInstanceState);


/**得到手机通讯录联系人信息**/
private void getPhoneContacts()
...
mContactsName.add(contactName);
mContactsNumber.add(phoneNumber);
mContactsPhonto.add(contactPhoto);


phoneCursor.close();


参考技术A 你没有往你的Adapter里添加数据。如果你要调用Adapter.notifyDatasetChanged()这个方法,你只能王Adapter里面的List添加数据,而不能每次都给一个新的List对象,否则也无法刷新数据。追问

我做的是程序调用通讯录先读取联系人姓名电话头像,再点击按钮修改联系人头像,点击按钮把图片给联系人设上了,然后想让listview叶更新一下,但listview显示的还是原来的头像(通讯录里的新头像已经设置上了),
不是添加,是更新,Adapter.notifyDatasetChanged()就不起作用吗?那要怎么做呢?

本回答被提问者和网友采纳
参考技术B 没看太懂你的代码,但是可以告诉你肯定是可以刷新的,就是那两个方法,你在自己看看那。追问

是我位置设的不对吗?还是应该用handler

追答

看不到你放哪里了,一般都是线setadapter(xxxx)后,每修改显示数据后调用xxxx.notifyda....,
注意必须是统一的实例。

Android Listview & Adapter

Listview主要有两个职责:

  • 将数据填充到布局  
  • 处理用户的选择点击等操作

列表的显示需要三个元素:

  • ListVeiw 用来展示列表的View
  • 适配器(Adapter) 用来把数据映射到ListView上的中介
  • 数据(data)    具体的将被映射的字符串,图片,或者基本组件

首先要了解什么是适配器:  

  适配器是一个连接数据和AdapterView(ListView就是一个典型的AdapterView)的桥梁,通过它能有效地实现数据与AdapterView的分离设置,使AdapterView与数据的绑定更加简便,修改更加方便。

Android中提供了很多的Adapter,常用的有4种:

  • ArrayAdapter<T>    ---->用来绑定一个数组,支持泛型操作
  • SimpleAdapter        ---->用来绑定在xml中定义的控件对应的数据
  • SimpleCursorAdapter -->用来绑定游标得到的数据
  • BaseAdapter           ---->通用的基础适配器

今天我们就来学习一下ListView & BaseAdapter

1.Layout.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="match_parent"
      android:orientation="vertical" >
  
      <ListView
          android:id="@+id/listView1"
          android:layout_width="match_parent"
          android:layout_height="match_parent" >
         
     </ListView>
 
 </LinearLayout>

2.为Listview添加的item设置显示样式

<?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="horizontal" >
  
      <ImageView
          android:id="@+id/imageView1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_margin="10dp"
          android:src="@drawable/tou1" />
 
      <LinearLayout
          android:layout_weight="1"
          android:layout_width="match_parent"
          android:layout_height="80dp"
          android:orientation="vertical" 
          android:layout_margin="5dp"
         >
       <TextView
        
          android:id="@+id/tv_userName"
          android:layout_width="match_parent"
          android:layout_height="20dp"
         />
         
        <TextView
          android:id="@+id/tv_lastMessage"
          android:layout_width="match_parent"
          android:layout_height="15dp"
          />
         
     </LinearLayout>
     
     <TextView
          android:id="@+id/tv_datetime"
          android:layout_width="150dp"
          android:layout_height="15dp"
         />
 </LinearLayout>

3.模拟数据库插入,先创建一个实体类

 package com.example.entity;
 
 public class Message {
      private String tou1;
      private String userName;
      private String lastMessage;
      private String datetime;
      
      public String getTou1() {
         return tou1;
     }
     public void setTou1(String tou1) {
         this.tou1 = tou1;
     }
     public String getUserName() {
         return userName;
     }
     public void setUserName(String userName) {
         this.userName = userName;
     }
     public String getLastMessage() {
         return lastMessage;
     }
     public void setLastMessage(String lastMessage) {
         this.lastMessage = lastMessage;
     }
     public String getDatetime() {
         return datetime;
     }
     public void setDatetime(String datetime) {
         this.datetime = datetime;
     }
 }

4.对listview进行数据的获取

package com.example.winxin2;
  
  import java.util.ArrayList;
  import java.util.List;
   
  import com.example.entity.Message;
   
  import android.app.Activity;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.ContextMenu;
  import android.view.ContextMenu.ContextMenuInfo;
  import android.view.LayoutInflater;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnCreateContextMenuListener;
  import android.view.ViewGroup;
  import android.widget.AdapterView;
  import android.widget.AdapterView.OnItemClickListener;
  import android.widget.BaseAdapter;
  import android.widget.ListView;
  import android.widget.TextView;
  import android.widget.Toast;
  
  
  public class MainActivity extends Activity {
  
      private ListView lv;
      private List<Message> messageList = new ArrayList<Message>();
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.weixin);
          
          //模拟读取数据库或者互联网
          for (int i = 0; i < 100; i++) {
              Message m = new Message();
              m.setTou1("xxx");
              m.setUserName("张三疯"+i);
              m.setLastMessage("今晚有约,一起华山论剑");
              m.setDatetime("11月11日");
              messageList.add(m);
          }
          
          
          lv = (ListView)findViewById(R.id.listView1);
          //简单理解为VC绑在一起
          lv.setAdapter( new BaseAdapter(){
  
              //返回多少条记录
             @Override
              public int getCount() {
                  // TODO Auto-generated method stub
                  return messageList.size();
              }
              //每一个item项,返回一次界面
              @Override
              public View getView(int position, View convertView, ViewGroup parent) {
                  View view = null;
                  
                  //下面的半段是为了让我们在拉伸的时候更顺畅,即之前取出的数据我们可以在缓存在获取,不需要在重新获取一次
                  //布局不变,数据变
                  
                  //如果缓存为空,我们生成新的布局作为1个item
                  if(convertView==null){
                      Log.i("info:", "没有缓存,重新生成"+position);
                      LayoutInflater inflater = MainActivity.this.getLayoutInflater();
                      //因为getView()返回的对象,adapter会自动赋给ListView
                      view = inflater.inflate(R.layout.listview_item_layout, null);
                  }else{
                      Log.i("info:", "有缓存,不需要重新生成"+position);
                      view = convertView;
                  }
                  Message m = messageList.get(position);
                  
                  TextView tv_userName = (TextView)view.findViewById(R.id.tv_userName);
                  tv_userName.setText(  m.getUserName()  );
                  tv_userName.setTextSize(15);
                 
                  TextView tv_lastMessage = (TextView)view.findViewById(R.id.tv_lastMessage);
                  tv_lastMessage.setText(  m.getLastMessage()  );
                  tv_lastMessage.setTextSize(12);
                  
                  TextView tv_datetime = (TextView)view.findViewById(R.id.tv_datetime);
                  tv_datetime.setText( m.getDatetime()  );
                  tv_datetime.setTextSize(12);
  
                  return view;
              }
              
              @Override
              public Object getItem(int position) {
                  // TODO Auto-generated method stub
                  return null;
              }
  
              @Override
             public long getItemId(int position) {
                 // TODO Auto-generated method stub
                 return 0;
             }
 
             
             
         } );
         
         //给ListView添加点击事件
         lv.setOnItemClickListener(new OnItemClickListener() {
 
             @Override
             public void onItemClick(AdapterView<?> parent, View view,
                     int position, long id) {
                 Message getList = messageList.get(position); 
                 String infoId = getList.getTou1(); //获取信息id  
                 String infoTitle = getList.getUserName();    //获取信息标题  
                 String infoDetails = getList.getLastMessage();    //获取信息详情  
                   
                 //Toast显示测试  
                 Toast.makeText(MainActivity.this, "信息ID:"+infoId,Toast.LENGTH_SHORT).show(); 
             }
             
         });
         
         //长按菜单显示  
         lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {  
             public void onCreateContextMenu(ContextMenu conMenu, View view , ContextMenuInfo info) {  
                 /*
                  * 参数menu:参数menu为事件的上下文菜单。
 
                     参数v:参数v为事件源View,当该View获得焦点时才可能接收该方法的事件响应。
 
                     参数info:info对象中封装了有关上下文菜单额外的信息,这些信息取决于事件源View。
                  */
                 conMenu.setHeaderTitle("菜单");  
                 conMenu.add(0, 0, 0, "条目一");  
                 conMenu.add(0, 1, 1, "条目二");  
                 conMenu.add(0, 2, 2, "条目三");  
             }  
         }); 
      
         }    
    
     //长按菜单处理函数  
     public boolean onContextItemSelected(MenuItem aItem) {  
         AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)aItem.getMenuInfo();  
         switch (aItem.getItemId()) {  
              case 0:  
                  Toast.makeText(MainActivity.this, "你点击了条目一",Toast.LENGTH_SHORT).show();  
                  return true;  
              case 1:  
                  Toast.makeText(MainActivity.this, "你点击了条目二",Toast.LENGTH_SHORT).show();  
                
                  return true;  
              case 2:  
                  Toast.makeText(MainActivity.this, "你点击了条目三",Toast.LENGTH_SHORT).show();  
                  return true;  
         }  
         return false;  
    }  
 }

 

谢谢大家的关注。欲向海天寻月去,五更飞梦渡鲲洋

以上是关于android listview不能刷新 adapter.notifyDataSetChanged()和setListAdapter(myAdapter)都不好用的主要内容,如果未能解决你的问题,请参考以下文章

Android Listview & Adapter

Android中Adapter刷新数据问题

android中如何获得listview中的checkbox的值?

android ListView刷新焦点问题

ListView / SimpleAdapter 不刷新 - Android

android listview数据刷新后保持原来的位置