在开始之前,我检查了Stackoverflow.com中的所有其他答案。 很抱歉打开另一个旧的notifyDataSetChanged() - 没有工作的东西。
如果我找到答案,我会回答我自己的问题。
嗨,我很难使用ListViewAdapter扩展BaseAdapter,如下所示。 在Stackoverflow.com或许多其他博客中,有很多关于这个问题的讨论。 解决方案似乎趋同于说
1)不要忘记设置setListAdapter。 2)添加新数据时使用notifyDataSetChanged()。 (有人说使用notifyDataSetInvalidate ...)
我一直在研究的教程是
http://adilsoomro.blogspot.kr/2012/12/android-listview-with-speech-bubble.html
问题是有时候效果很好,但有时却没有。
没有模式。
由于消息是从其他系统传输的,我认为这是由于网络问题。 但所有的消息都无缝地进入我的应用程序。
我没有在ListViewActivity上使用ArrayList实例的原因是 从某些系统操作点发生一个ArrayList实例的情况 ListViewAdapter中的内容无法与ListViewActivity上的arrayList同步。 而且我已经证实,那里开始存在一个时刻 一些消息被放入列表A(ListViewActivty内)和其他消息中 列表B(在ListViewAdapter中,但我不确定是否真的如此)。 这就是我删除ListViewActivty中的arraylist的原因。
更新在AsyncTask的onPostExecute部分内完成,而不是使用runUiThread (使用runUiThread并没有区别。)
我发现当列表视图没有更新时,getView()也没有被调用, 即使适配器中的消息列表已添加数据并且getCount()返回 准确的刷新数据大小。
我怀疑onPostExecute中的操作偶尔会被阻止 一些未知的过程。
当我在我的应用上发布UI事件(例如,输入文本)时, 它会对屏幕上添加的数据进行后期刷新 在调用addNewMessage()时已经完成了。
=============================================== ========================
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;
}
}
答案 0 :(得分:0)
这不是处理这个问题的一种认证方式。
但是目前我已经通过添加以下方法做了一些解决方法。 这在每1秒内在一些单独的线程中调用。 因此无论实际是否添加了新数据,都只是 做notifyDataSetChanged(),如果真的有一些项目添加但是 如上所述,无法在UI上看到它,它将在用户屏幕上刷新。
public void refresh()
{
this.runOnUiThread
(
new Runnable()
{
@Override
public void run()
{
adapter.notifyDataSetChanged();
getListView().setSelection( adapter.observeMessageList().size() - 1 );
}
});
}
如果我找到一些根本原因,我会详细说明这个问题。