【问题标题】:How to refresh a ListView from a BroadcastReceiver?如何从 BroadcastReceiver 刷新 ListView?
【发布时间】:2014-10-02 14:28:11
【问题描述】:

如果我在与我的 ListView 关联的自定义适配器上调用 notifyDataSetChanged(),则所有视图都应自行刷新(将调用 getView())。 现在我有一个正在监听事件的 BroadcastReceiver。当事件触发时,必须刷新 ListView。我怎样才能做到这一点? 谢谢!

【问题讨论】:

  • "现在我有一个正在监听事件的 BroadcastReceiver" -- 事件是什么,BroadcastReceiver 是如何注册的(清单或registerReceiver())?
  • 嗨,动态注册在包含 ListView 的 Activity 中,事件是来自 DownloadManager 的 ACTION_DOWNLOAD_COMPLETE。
  • 在广播接收器实现的 onReceive 中,您必须:修改自定义适配器的底层数据并调用 notifyDataSetChanged 或创建新的自定义适配器并将其设置为列表视图
  • @Selvin 如果我可以从接收器访问列表视图,那会很容易。我可以调用 getAdapter。我不知道如何从接收器访问列表视图(避免静态或吸气剂)
  • 你说你有来自活动的动态接收器......所以我认为代码看起来像blog.vogella.com/2011/06/14/android-downloadmanager-example 然后你访问内部的列表视图 onReceive (findViewById(R .id.id_of_listview)应该可以工作,因为这个实现将不是 Activity 的静态内部类)

标签: android listview broadcastreceiver notifydatasetchanged


【解决方案1】:

如果您从接收器刷新列表视图,您将获得如下代码:

BroadcastReceiver br;
public final static String BROADCAST_ACTION = "BROADCAST_ACTION";
br = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//code refreshing...
}
};
IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(br, intFilt);

你用代码调用它:

Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);

如果您需要将刷新作为另一个操作,您只需添加(操作后):

Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);

【讨论】:

  • 它工作不正常。请详细说明您的答案。
  • 我认为“//代码刷新...”部分是这里的难点。
【解决方案2】:

根据要求,请看下面的示例代码:

public interface OnDataUpdateListener {
    void onDataAvailable(ArrayList<String> newDataList);
}

public class MyTestReceiver extends BroadcastReceiver {
    public static final String DATA_LIST = "DATA_LIST";
    private OnDataUpdateListener mDataUpdateListener = null;
    public MyTestReceiver(OnDataUpdateListener dataUpdateListener) {
        mDataUpdateListener = dataUpdateListener;
    }

    @Override
    public void onReceive(Context ctx, Intent intent) {
        // assuming data is available in the delivered intent
        ArrayList<String> dataList = intent.getSerializableExtra(DATA_LIST);
        if (null != mDataUpdateListener) {
            mDataUpdateListener.onDataAvailable(dataList);
        }
    }
}

public class MyActivity extends FragmentActivity implements OnDataUpdateListener {
    public static final String ACTION_DATA_UPDATE_READY = "ACTION_DATA_UPDATE_READY";
    private MyTestReceiver mTestReceiver = null;
    private <SomeAdapterClass> mAdapter = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // other required initialization 
        mTestReceiver = new MyTestReceiver(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (null != mTestReceiver) {
            registerReceiver(mTestReceiver, new IntentFilter(ACTION_DATA_UPDATE_READY));
        }
    }

    void onDataAvailable(ArrayList<String> newDataList) {
        // assuming you want to replace existing data and not willing to append to existing dataset
        mAdapter.clear();
        mAdapter.addAll(newDataList);
        mAdapter.notifyDataSetChanged();
    }
}

【讨论】:

    【解决方案3】:

    在更新数据的代码中,发出一条消息,表明数据已更改... (您需要访问 Activity 或 Application 上下文才能执行此操作)

    Intent intent = new Intent("ListViewDataUpdated");
    LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
    

    然后在您的活动中使用以下代码捕获消息,并告诉您的 ListAdapter 更新...

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
                myListAdapter.notifyDataSetChanged();
               }
            };
    
    @Override
    public void onResume(){
      super.onResume();
      LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("ListViewDataUpdated"));
      myListAdapter.notifyDataSetChanged();//in case our data was updated while this activity was paused
    }
    
    
    @Override
    protected void onPause() {
       LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
       super.onPause();
    }
    

    来源:改编自 Vogella

    【讨论】:

      【解决方案4】:

      LocalBroadcastManager.getInstance(context.sendBroadcast(intent));

      改成

      LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

      我可能错了,但它对我有用...

      【讨论】:

        猜你喜欢
        • 2016-01-17
        • 1970-01-01
        • 1970-01-01
        • 2015-10-12
        • 2021-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-15
        相关资源
        最近更新 更多