Android 处理emptylist和asynctask

Android 处理emptylist和asynctask,android,listview,Android,Listview,我使用Cyril Mottier编写的有用代码,其中的空状态为ListView在ViewStub中使用id@android:id/empty充气。在这个方法中,一切都很好,但是如果我通过setListAdapter或附加的空适配器在ListActivity中没有附加的适配器,那么我会看到空视图。一切都很清楚,但如果我想实现这样的逻辑: 打开ListActivity 连接适配器 执行AcyncTask并获取适配器的数据,显示进度对话框 调用notifyDataSetChanged 取消对话框 然后

我使用Cyril Mottier编写的有用代码,其中的空状态为
ListView
ViewStub
中使用id
@android:id/empty
充气。在这个方法中,一切都很好,但是如果我通过
setListAdapter
或附加的空适配器在
ListActivity
中没有附加的适配器,那么我会看到空视图。一切都很清楚,但如果我想实现这样的逻辑:

  • 打开
    ListActivity
  • 连接
    适配器
  • 执行
    AcyncTask
    并获取适配器的数据,显示进度对话框
  • 调用notifyDataSetChanged
  • 取消对话框
  • 然后,从1到3个步骤中,我查看带有错误的空视图(例如“未找到”)。但我只想在执行
    AsyncTask
    后显示错误。在执行
    AsyncTask
    期间,我只想显示进程对话框。我尝试使用
    @android:id/empty的可见性选项,尝试在
    xml
    中使用
    include
    。但我无法理解这个逻辑。任何建议都将不胜感激

    UPD:更多信息 我有
    activity.xml

    <FrameLayout
        android:id="@id/gd_action_bar_content_view"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    
        <ListView
            android:id="@android:id/list"
            style="@style/listViewStyle"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:focusable="false" />
    
         <ViewStub
            android:id="@android:id/empty"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            layout="@layout/error" />
    
    </FrameLayout>
    
    和异步类:

    private class SearchAndFill extends AsyncTask<String, Void, List<Object>>{
        LoadingDialog dialog;
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (dialog==null){
                dialog = new LoadingDialog(MyListActivity.this);
                dialog.setCancelable(false);
            }
            dialog.show();
        }
    
        @Override
        protected List<Object> doInBackground(String... str) {
            return search(str[0]); //this is HTTP GET request
        }
    
        @Override
        protected void onPostExecute(List<Object> result) {
            super.onPostExecute(result);
            dialog.dismiss();
            showResult(result); //this is fill adapter data and call notifyDataSetChanged
        }
    }
    
    私有类SearchAndFill扩展了异步任务{
    加载对话框;
    @凌驾
    受保护的void onPreExecute(){
    super.onPreExecute();
    如果(对话框==null){
    dialog=新建加载对话框(MyListActivity.this);
    对话框。可设置可取消(false);
    }
    dialog.show();
    }
    @凌驾
    受保护列表doInBackground(字符串…str){
    返回搜索(str[0]);//这是HTTP GET请求
    }
    @凌驾
    受保护的void onPostExecute(列表结果){
    super.onPostExecute(结果);
    dialog.dismise();
    showResult(result);//这是填充适配器数据并调用notifyDataSetChanged
    }
    }
    

    当活动创建并膨胀
    activity.xml
    时,它会显示为空,然后执行
    AsyncTask
    ,而执行
    AsyncTask
    时,我会看到空视图。当调用
    onPostExecute
    方法
    AsyncTask
    时,我看到了HTTP GET请求的结果。当活动创建并膨胀
    activity.xml
    时,它显示为空,然后执行
    AsyncTask
    ,而
    AsyncTask
    执行时,我看到空视图。当调用
    onPostExecute
    方法
    AsyncTask
    时,我看到了HTTP GET请求的结果。我认为这是错误的。我希望在执行AsyncTask之前和之后显示空白ListView,如果结果等于Collections.EMPTY\u LIST我希望显示带有图像的文本(例如找不到任何内容)

    我建议您尝试将空视图的文本值设置为空字符串(
    “”
    ),然后在AsyncTask完成时将文本值更改为错误消息


    希望它能解决你的问题。

    据我所知,这就是你想要实现的目标

    public class MyListActivity extends ListActivity implements OnScrollListener, OnItemClickListener{
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity); //inflate activity with ViewStub
            ((ViewStub) findViewById(R.id.YOUR_VIEW_STUB_ID)).setVisibility(View.GONE);
            mAdapter = new MyAdapter(this, Collections.EMPTY_LIST); 
            setListAdapter(mAdapter);
            new SearchAndFill().execute("");
        }
    }
    
    ...    ...    ....
    
    private class SearchAndFill extends AsyncTask<String, Void, List<Object>>{
    LoadingDialog dialog;
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (dialog==null){
            dialog = new LoadingDialog(MyListActivity.this);
            dialog.setCancelable(false);
        }
        dialog.show();
    }
    
    @Override
    protected List<Object> doInBackground(String... str) {
        return search(str[0]); //this is HTTP GET request
    }
    
    @Override
    protected void onPostExecute(List<Object> result) {
        super.onPostExecute(result);
        if (result == null || result.size() == 0){
            mAdapter.notifyDataSetInvalidated();
            ((ViewStub) findViewById(R.id.YOUR_VIEW_STUB_ID)).setVisibility(View.VISIBLE);
        } else {
            // add stuff to mAdapter here...
            mAdapter.notifyDataSetChanged();
        }
        dialog.dismiss();
    }
    
    公共类MyListActivity扩展ListActivity实现OnScrollListener、OnItemClickListener{
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);//使用ViewStub膨胀活动
    ((ViewStub)findViewById(R.id.YOUR_VIEW_STUB_id)).setVisibility(VIEW.GONE);
    mAdapter=newmyadapter(此为Collections.EMPTY_列表);
    setListAdapter(mAdapter);
    新建SearchAndFill()。执行(“”);
    }
    }
    ...    ...    ....
    私有类SearchAndFill扩展了异步任务{
    加载对话框;
    @凌驾
    受保护的void onPreExecute(){
    super.onPreExecute();
    如果(对话框==null){
    dialog=新建加载对话框(MyListActivity.this);
    对话框。可设置可取消(false);
    }
    dialog.show();
    }
    @凌驾
    受保护列表doInBackground(字符串…str){
    返回搜索(str[0]);//这是HTTP GET请求
    }
    @凌驾
    受保护的void onPostExecute(列表结果){
    super.onPostExecute(结果);
    if(result==null | | result.size()==0){
    mAdapter.notifyDataSetionValidated();
    ((ViewStub)findViewById(R.id.YOUR_VIEW_STUB_id)).setVisibility(VIEW.VISIBLE);
    }否则{
    //在这里向mAdapter添加内容。。。
    mAdapter.notifyDataSetChanged();
    }
    dialog.dismise();
    }
    

    请考虑修改您的问题并添加一些代码。我发现这很难理解,即使我不明白为什么你在开始时看到ViewStub,当你改变可见性或显式调用infalte时它会膨胀。这个评论是决定性的,我注意到如果
    ViewStub
    将有
    android:id=“@android:id/empty”
    ,它将在setContentView上自动可见。最后,至少有一些动作。如果你按照答案上写的去做,那么一切都会成功。但膨胀的ViewStub覆盖了一切,即使数据不是空的。
    private class SearchAndFill extends AsyncTask<String, Void, List<Object>>{
        LoadingDialog dialog;
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (dialog==null){
                dialog = new LoadingDialog(MyListActivity.this);
                dialog.setCancelable(false);
            }
            dialog.show();
        }
    
        @Override
        protected List<Object> doInBackground(String... str) {
            return search(str[0]); //this is HTTP GET request
        }
    
        @Override
        protected void onPostExecute(List<Object> result) {
            super.onPostExecute(result);
            dialog.dismiss();
            showResult(result); //this is fill adapter data and call notifyDataSetChanged
        }
    }
    
    public class MyListActivity extends ListActivity implements OnScrollListener, OnItemClickListener{
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity); //inflate activity with ViewStub
            ((ViewStub) findViewById(R.id.YOUR_VIEW_STUB_ID)).setVisibility(View.GONE);
            mAdapter = new MyAdapter(this, Collections.EMPTY_LIST); 
            setListAdapter(mAdapter);
            new SearchAndFill().execute("");
        }
    }
    
    ...    ...    ....
    
    private class SearchAndFill extends AsyncTask<String, Void, List<Object>>{
    LoadingDialog dialog;
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (dialog==null){
            dialog = new LoadingDialog(MyListActivity.this);
            dialog.setCancelable(false);
        }
        dialog.show();
    }
    
    @Override
    protected List<Object> doInBackground(String... str) {
        return search(str[0]); //this is HTTP GET request
    }
    
    @Override
    protected void onPostExecute(List<Object> result) {
        super.onPostExecute(result);
        if (result == null || result.size() == 0){
            mAdapter.notifyDataSetInvalidated();
            ((ViewStub) findViewById(R.id.YOUR_VIEW_STUB_ID)).setVisibility(View.VISIBLE);
        } else {
            // add stuff to mAdapter here...
            mAdapter.notifyDataSetChanged();
        }
        dialog.dismiss();
    }