Android BaseAdapter notifyDataSetChanged()有时有效,有时无效';T

Android BaseAdapter notifyDataSetChanged()有时有效,有时无效';T,android,listview,Android,Listview,在开始之前,我检查了Stackoverflow.com上的所有其他答案。 很抱歉提出另一个相同的旧notifyDataSetChanged()-不起作用的东西 如果我找到答案,我会回答我自己的问题 您好,我在使用ListViewAdapter时遇到困难,它扩展了BaseAdapter,如下所示。 Stackoverflow.com或许多其他博客上都有很多关于这个问题的讨论。 这个解决方案似乎是一致的 1) 不要忘记设置setListAdapter。 2) 添加新数据时使用notifyDataSe

在开始之前,我检查了Stackoverflow.com上的所有其他答案。 很抱歉提出另一个相同的旧notifyDataSetChanged()-不起作用的东西

如果我找到答案,我会回答我自己的问题

您好,我在使用ListViewAdapter时遇到困难,它扩展了BaseAdapter,如下所示。 Stackoverflow.com或许多其他博客上都有很多关于这个问题的讨论。 这个解决方案似乎是一致的

1) 不要忘记设置setListAdapter。 2) 添加新数据时使用notifyDataSetChanged()。(有人说使用notifyDataSetValidate…)

我一直在学习的教程是

问题是它有时工作得很好,但有时却不行

没有模式

由于消息是从其他系统传输的,我认为这是由于网络问题。 但是所有的信息都无缝地进入了我的应用程序

我没有在ListViewActivity上使用ArrayList实例的原因是 从系统操作的某个角度来看,ArrayList实例 ListViewAdapter内部无法与ListViewActivity上的arrayList同步。 我已经证实,有一个时刻开始存在 一些消息放入列表A(在ListViewActivty中),其他消息放入 列表B(在ListViewAdapter中,但我不确定是否确实如此)。 这就是为什么我删除了ListViewActivty中的arraylist

更新是在AsyncTask的onPostExecute部分内完成的,而不是使用runUiThread (使用runUiThread和不使用runUiThread没有区别)

我发现当列表视图没有更新时,getView()也没有被调用, 即使适配器中的消息列表已添加数据并返回getCount() 刷新数据大小的确切数目

我怀疑onPostExecute中的操作偶尔会被 一些未知的过程

当我在我的应用程序上给出UI事件(例如,输入文本)时, 它对屏幕上添加的数据进行了延迟刷新,这应该 已在调用addNewMessage()时完成()

=========================================================================================================

1.调用addNewMessage()的AsycTask(ListViewActivity.java的一部分) =========================================================================================================

3.ListViewActivity将ListViewAdapter设置为观察者 =========================================================================================================

4.具有存储数据项的实际arrayList的ListViewAdapter.java
import java.util.ArrayList;
导入java.util.Iterator;
导入com.test.R;
导入android.content.Context;
导入android.util.Log;
导入android.view.Gravity;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.BaseAdapter;
导入android.widget.LinearLayout.LayoutParams;
导入android.widget.TextView;
// http://stackoverflow.com/questions/3669325/notifydatasetchanged-example
公共类ListViewAdapter扩展了BaseAdapter
{
私有上下文;
公共静态ArrayList mMessages=新ArrayList();
公共ListViewAdapter(上下文)
{
超级();
this.mContext=上下文;
}
公共无效clearMessages()
{
ListViewAdapter.mMessages.clear();
}
公共无效添加(消息_消息)
{
ListViewAdapter.mMessages.add(_message);
}
公共阵列列表观察者消息传递者()
{
返回ListViewAdapter.m消息;
}
@凌驾
public int getCount()
{ 
返回mMessages.size();
} 
@凌驾
公共对象getItem(int位置)
{       
返回消息。获取(位置);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图)
{
com.test.Message Message=(com.test.Message)this.getItem(position);
视窗座;
if(convertView==null)
{
holder=新的ViewHolder();
convertView=LayoutFlater.from(mContext).充气(R.layout.sms_行,父级,false);
holder.message=(TextView)convertView.findViewById(R.id.message\u text);
convertView.setTag(支架);
}
其他的
{
holder=(ViewHolder)convertView.getTag();
}
holder.message.setText(message.getMessage());
LayoutParams lp=(LayoutParams)holder.message.getLayoutParams();
//检查是否为状态消息,然后删除背景,并更改文本颜色。
if(message.isStatusMessage())
{
holder.message.setBackgroundDrawable(空);
lp.gravity=gravity.LEFT;
//holder.message.setTextColor(R.color.textFieldColor);
}
其他的
{       
//检查消息是否是我的,以显示绿色背景并向右对齐
if(message.isMine())
{
holder.message.setBackgroundResource(R.drawable.speech\u bubble\u green);
lp.gravity=gravity.RIGHT;
}
//若不是我的,那个么它是从发送方显示橙色背景并向左对齐
其他的
{
holder.message.setBackgroundResource(R.drawable.speech\u bubble\u橙色);
lp.gravity=gravity.LEFT;
}
holder.message.setLayoutParams(lp);
//holder.message.setTextColor(R.color.textColor);
}
返回视图;
}
公共静态类视图持有者
{
文本视图消息;
}
@凌驾
// http://stackoverflow.com/questions/6711592/what-is-the-intent-of-the-methods-getitem-and-getitemid-in-the-android-class-bas
公共长getItemId(int位置)
{
//未实现,因为我们没有使用Sqlite。
// http://stackoverflow.com/questions/24223393/android-listview-custom-adapter-getview-never-called-up
返回0;
//返回位置;
}

}

这不是解决这个问题的独创方法

但目前我通过添加下面的方法做了一些变通。 这是在某个单独的线程内每秒调用一次。 所以不管n是否真的
private class RefreshListView extends AsyncTask<Argument, String, Argument>
{
@Override
protected Argument doInBackground(Argument... _args) 
{ 
     Argument result = new Argument();

     result.setMessageString( _args[0].getMessageString() );
     result.setIsMine( _args[0].getIsMine() );

     return result;
}

      @Override
public void onProgressUpdate(String... v) 
{ 

}

@Override
protected void onPostExecute(Argument _arg ) 
{
    addNewMessage(new Message( _arg.getMessageString(), _arg.getIsMine() ) );  
}
} 
public void addNewMessage( final Message _message )
{
    adapter.add( _message ); 
    adapter.notifyDataSetChanged();
    getListView().setSelection( adapter.observeMessageList().size() - 1 );
}
public void onCreate( Bundle savedInstanceState ) 
{
    adapter = new ListViewAdapter( this );
    this.setListAdapter( adapter );
}
import java.util.ArrayList;
import java.util.Iterator;

import com.test.R;

import android.content.Context;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

// http://stackoverflow.com/questions/3669325/notifydatasetchanged-example
public class ListViewAdapter extends BaseAdapter
{
private Context mContext;

public static ArrayList<com.test.Message> mMessages = new ArrayList<com.test.Message>();

public ListViewAdapter(Context context ) 
{
     super();

     this.mContext = context;
}

public void clearMessages()
{
    ListViewAdapter.mMessages.clear();
}

public void add( Message  _message )
{
    ListViewAdapter.mMessages.add( _message );
}

public ArrayList<com.test.Message> observeMessageList()
{
     return ListViewAdapter.mMessages;
}

@Override
public int getCount() 
{ 
    return mMessages.size();
} 


@Override
public Object getItem( int position ) 
{       
    return mMessages.get( position );
}


@Override
public View getView( int position, View convertView, ViewGroup parent ) 
{
    com.test.Message message = (com.test.Message) this.getItem(position);

    ViewHolder holder; 

    if ( convertView == null )
    {
        holder = new ViewHolder();

        convertView = LayoutInflater.from(mContext).inflate(R.layout.sms_row, parent, false);

        holder.message = (TextView) convertView.findViewById(R.id.message_text);

        convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.message.setText( message.getMessage() );

    LayoutParams lp = (LayoutParams) holder.message.getLayoutParams();

    // check if it is a status message then remove background, and change text color.
    if ( message.isStatusMessage() )
    {
        holder.message.setBackgroundDrawable(null);

        lp.gravity = Gravity.LEFT;

        // holder.message.setTextColor( R.color.textFieldColor );
    }
    else
    {       
        // Check whether message is mine to show green background and align to right
        if ( message.isMine() )
        {
            holder.message.setBackgroundResource(R.drawable.speech_bubble_green);
            lp.gravity = Gravity.RIGHT;
        }
        // If not mine then it is from sender to show orange background and align to left
        else
        {
            holder.message.setBackgroundResource(R.drawable.speech_bubble_orange);
            lp.gravity = Gravity.LEFT;
        }

        holder.message.setLayoutParams(lp);

        // holder.message.setTextColor( R.color.textColor );    
    }

    return convertView;
}

public static class ViewHolder
{
    TextView message;
}

@Override
// http://stackoverflow.com/questions/6711592/what-is-the-intent-of-the-methods-getitem-and-getitemid-in-the-android-class-bas
public long getItemId(int position) 
{
    // Unimplemented, because we aren't using Sqlite.

    // http://stackoverflow.com/questions/24223393/android-listview-custom-adapter-getview-never-called-up
    return 0;
    // return position;
}
public void refresh()
{
     this.runOnUiThread
     ( 
        new Runnable() 
        { 
            @Override 
            public void run() 
            { 
                  adapter.notifyDataSetChanged();

                  getListView().setSelection( adapter.observeMessageList().size() - 1 );
            } 
     });  
}