ArrayAdapter 更新列表 - 没有按预期工作?

Posted

技术标签:

【中文标题】ArrayAdapter 更新列表 - 没有按预期工作?【英文标题】:ArrayAdapter updating list - not working as expected? 【发布时间】:2014-04-23 09:02:47 【问题描述】:

好的,所以我有一个 ArrayAdapter,我有这个显示行,每行包含一些文本和一个删除按钮。删除按钮是我的问题......我有一个监听器监听点击,然后它调用remove(position) 删除视图。 (这就是我想要的)......虽然当我在 UI 线程中调用 onNotifyDataSetChanged() 时,它会重新添加已删除的行,这可能是因为它没有从该列表中删除(仅视图)......我不知道关于如何解决这个问题。

总结一下……

我可以使用删除按钮删除我想要删除的视图,但在调用 onNotifyDataSetChanged() 后,视图会被重新添加。

主要活动

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    render = new tweetView(this);

    LinearLayout canvas = (LinearLayout)findViewById(R.id.content_frame);
    final ListView tweetList = (ListView)findViewById(R.id.tweetView);

    tweetListFull = new ArrayList<Tweet>();
    int resID = R.layout.tweet;
    aa = new tweetAdapter(this, resID, tweetListFull);

    Log.w("Check","Here1");        
    tweetList.setAdapter(aa);
    Log.w("Check","Here1");
    //tweetList.addView()
    canvas.addView(render);
    tweetList.setClickable(true);
    tweetList.setOnItemClickListener(new ListView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> a, View v, int i, long l) 

            try 
                //Nothing here yet.

            
            catch(Exception e) 
               // System.out.println("Nothing here yet.);
            
        
    ); 

    // UI //        
    drawerListViewItems = getResources().getStringArray(R.array.items); 
    // get ListView defined in activity_main.xml
    drawerListView = (ListView) findViewById(R.id.left_drawer); 
    // Set the adapter for the list view
    drawerListView.setAdapter(new ArrayAdapter<String>(this,R.layout.drawer_listview_item, drawerListViewItems));
LocationManager locationManager;
    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    String provider = LocationManager.GPS_PROVIDER;

    int updateTime = 5000; // 5 seconds.
    int distance = 1; // meters 

    LocationListener myLocListener = new LocationListener()
        @Override
        public void onLocationChanged(Location arg0) 
            Log.w("location",String.valueOf(arg0));
            twitterTest tweet = new twitterTest();
            Log.w("Test","Location Changed");
            Log.w("test","Long: "+String.valueOf(arg0.getLongitude())+ "Lat: "+String.valueOf(arg0.getLatitude()));
            tweet.execute(arg0.getLongitude(),arg0.getLatitude());  // The argument for this is the query to search for.

        
        @Override
        public void onProviderDisabled(String arg0) 
            // TODO Auto-generated method stub

        
        @Override
        public void onProviderEnabled(String arg0) 
            // TODO Auto-generated method stub

        
        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) 
            // TODO Auto-generated method stub

                   
    ;
    locationManager.requestLocationUpdates(provider, updateTime,distance, myLocListener);



tweetAdapter

package com.example.networkingcoursework;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.WebView.FindListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.TextView;

public class tweetAdapter extends ArrayAdapter<Tweet>

int resource;
Tweet tweet = null;
Context context;
//ArrayList<Tweet> tweetListFull;

public tweetAdapter(Context _context, int _resource,ArrayList<Tweet> _objects) 
    super(_context, _resource, _objects);
    resource = _resource;
    //tweetListFull = _objects;
    context = _context;
    // TODO Auto-generated constructor stub



@Override
public View getView(final int position, View convertView, ViewGroup parent)
    LinearLayout tweetView;
    tweet = getItem(position);

    String tweetStatus = tweet.getStatus();

    if(convertView == null)
        tweetView = new LinearLayout(getContext());
        String inflater = Context.LAYOUT_INFLATER_SERVICE;
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater);
        vi.inflate(resource,tweetView, true);
    
    else
        tweetView = (LinearLayout) convertView;     
    

    TextView idView = (TextView)tweetView.findViewById(R.id.tweetText);
    idView.setText(String.valueOf(tweetStatus));
    Button tweetClose = (Button)tweetView.findViewById(R.id.tweetClose);
    tweetClose.setOnClickListener(new OnClickListener()
        public void onClick(View v)
            int i = (Integer)v.getTag();

            remove(getItem(position));
            notifyDataSetChanged();
        
    );
    tweetClose.setTag(position);


    return tweetView;


【问题讨论】:

int i = (Integer)v.getTag();移除(获取项目(位置));不应该用i值代替位置吗? 刚刚对其进行了编辑尝试,但不幸的是它没有改变任何东西,视图仍然被删除,但 MainActivity 上的 onDataSetChanged() 继续导致它在 locationChange 后重绘。 【参考方案1】:

您似乎不需要notifyDataSetChanged,因为它包含来自活动的列表实例。这就是列表恢复其原始状态的原因。通过调用 remove,它正在更改列表。请参阅此类似主题以获得更好的解释:notifyDataSetChanged example

【讨论】:

感谢您的想法,不幸的是,在注释掉 notifyDataSetChanged 之后,列表仍然相同。我测试这个的方法是在我删除项目之前检查列表的长度,然后在我删除项目之后再次检查。前后列表大小保持为 15。只是要阅读您链接的线程。 找到另一个可能的解决方案。您正在使用字符串数组初始化 ArrayAdapter。它需要使用arrayList 进行初始化。当 ArrayAdapter 用数组初始化时,它不能被修改。更改此行 'drawerListViewItems = getResources().getStringArray(R.array.items);'查看此解决方案:link【参考方案2】:

正如here 所见,ArrayAdapter.remove() 不适用于 String[] 等普通 java 数组,而您可以在 MainActivity 中使用:

drawerListViewItems = getResources().getStringArray(R.array.items); 

考虑改用getStringArrayList。

另外也不需要手动调用notifyDataSetChange(),可以看this

【讨论】:

当我在适配器中使用ArrayList&lt;Tweet&gt; 时,这真的适用吗?我会阅读您链接的文档。 是的,你是对的,我没有看到你使用了 2 个适配器,抱歉 对不起,我应该指定的。

以上是关于ArrayAdapter 更新列表 - 没有按预期工作?的主要内容,如果未能解决你的问题,请参考以下文章

更新 Arrayadapter 中的数据

遍历两个列表的列表理解没有按预期工作[重复]

更新触发器..没有按预期工作?

如何从 Android 中 ArrayAdapter 上的 ArrayList 更新项目

为自定义 ArrayAdapter 实现 Fiterable 接口

MariaDB“更新级联”约束没有按预期工作?