Android 如何在ListView中显示空视图、进度视图和数据?

Android 如何在ListView中显示空视图、进度视图和数据?,android,listview,Android,Listview,这主要是一个概念问题。我正在活动中使用ListFragment。其列表必须显示以下信息之一: 项目清单 如果没有项目,则为空视图 从数据库加载数据时的“加载”视图 空视图由框架自动管理,因为onCreateView上的my ListFragment正在创建如下自定义视图: @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance){ if(

这主要是一个概念问题。我正在活动中使用ListFragment。其列表必须显示以下信息之一:

  • 项目清单
  • 如果没有项目,则为空视图
  • 从数据库加载数据时的“加载”视图
空视图由框架自动管理,因为onCreateView上的my ListFragment正在创建如下自定义视图:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance){
    if(Globals.DEBUG_LIFECYCLE)
        Log.d("Fragment", "ONCREATEVIEW");

    return inflater.inflate(R.layout.kanji_list, null);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance){
    View v = inflater.inflate(R.layout.kanji_list, null);
    mLoadingView = (LoadingView)v.findViewById(R.id.loading);
    mListContainer = (LinearLayout)v.findViewById(R.id.listcontainer);
    return v;
}
汉字列表的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView android:id="@id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:listSelector="@android:color/transparent" />

    <ch.shibastudio.kanjinotepad.list.KanjiListEmptyView android:id="@id/android:empty"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="@string/no_kanji"
        android:visibility="gone"/>
我通过调用以下方法显示/隐藏“加载”视图:

private void setLoadingViewVisible(boolean visible){
    if(null != mLoadingView && null != mListContainer){
        mListContainer.setVisibility(visible ? View.GONE : View.VISIBLE);
        mLoadingView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }
}

听起来您希望列表包含加载消息而不阻塞用户。我假定您已经找到了在数据获取完成时异步更新列表的方法

无论如何,我想到了几种方法

最简单的方法可能是在线性布局中有三个视图,并隐藏其中两个视图,只显示要显示的视图。例如,在加载时,您将隐藏id/android:list并公开显示“加载…”的视图。加载完成后,您将隐藏“加载…”并取消隐藏列表或“空”视图


另一种方法是使用三种列表项。看一看。子类适配器(或您正在使用的它的任何变体)并定义getViewTypeCount以返回3。然后定义getItemViewType以返回三个值中的一个,具体取决于要显示的内容。最后,增强getView(您必须已经拥有此函数的版本)以返回三种类型的视图。

这是一个与应用程序工作相关的非常具体的问题。话虽如此,我认为在您的情况下最好的做法是在
fragment
布局文件中有3个视图
ListView
在查询完成且项目计数非零时显示项目列表。查询进行时要使用的另一个
ProgressBar
视图。通过设置进度编号(默认值为0到100),您可以控制此
进度条的可见性
,或者如果您使用的是
不确定的
进度条样式,则可以使用视图的可见性来控制它的
可见性
。最后是一个
标签
文本视图
,当要显示的项目为零时使用-控制此视图的可见性<代码>列表视图
文本视图
在您的案例中是互斥的,这意味着当
列表视图
显示时,
文本视图
被隐藏。HTH

查看支持库附带的
列表片段
,它是一个副本

此类不同于常规的
ListFragment
,差异在
onCreateView
函数中可见。如果你看它,它提供的正是你所描述的

  • 在数据绑定到它之前,它提供了一个动画加载微调器
  • 它显示您希望在适配器中显示的任何数据,就像常规的
    ListFragment
  • 它有一个可选的空字段,您可以通过调用
    setEmptyText()

  • 因此,我建议您使用支持库的
    ListFragment
    副本,而不是普通的副本,或者使用我上面链接的源代码作为创建自己版本的类的垫脚石。

    我建议您在onCreateView中创建包含空视图的ListView。
    然后在启动中显示进度条。现在启动一个线程,否则ProgressBar可能不会显示,因为以下代码在主线程上运行。在这个线程中,加载数据,显示数据并关闭ProgressBar

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    
            View view = inflater.inflate(R.layout.list_view, container, false);
    
            return view;
    }
    
    public void onStart() {
        super.onStart();
    
        // ProgressBar
        new ProgressDialog(getActivity());
        final ProgressDialog dialog = ProgressDialog.show(getActivity(),
                getString(R.string.loading_title),
                getString(R.string.loading_msg), true, false);
    
        // get ListView
        final ListView myListView = (ListView) getView().findViewById(
                    R.id.listView1);
    
        Thread thread = new Thread() {
            @Override
            public void run() {
                //load your data here (fill Adapter)!
                loadData();
    
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // fill ListView, dismiss Dialog
                        myListView.setAdapter(yourAdapterWithData);
                        dialog.dismiss();
                        }
                    });
                }
            };
    
        thread.start();
    }
    

    这只是示例代码,无法正常工作…

    谢谢Kasra Rahjerdi,我将查看此源代码以获得灵感。通过查看您提供的链接中的源代码,我找到了解决方案(现在发布)。谢谢你,卡斯拉·拉赫迪!谢谢你的回答。然而,正如我在问题中所说,我不想使用对话框。但是你提出的解决方案可能是另一个应用程序的好主意。哦,对不起,我听说你想使用对话框。。。是我的错。想法仍然是一样的:创建一个视图(在您的案例中是图片),启动一个线程,一旦它完成,您就可以更改视图。[br]这可能有帮助解决方案是在2个xml文件中声明2个视图,然后切换它们。介绍了我喜欢在布局中另一个视图的想法,并在加载过程中隐藏ListView,谢谢你的想法,我会尝试一下!谢谢你Harikris,你的想法也为我指明了正确的方向。我把我的答案贴在问题的末尾。@Shibakaneki如果它对你有帮助,请在你有机会的时候投票。它也会帮助其他跟随你的人。谢谢
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    
            View view = inflater.inflate(R.layout.list_view, container, false);
    
            return view;
    }
    
    public void onStart() {
        super.onStart();
    
        // ProgressBar
        new ProgressDialog(getActivity());
        final ProgressDialog dialog = ProgressDialog.show(getActivity(),
                getString(R.string.loading_title),
                getString(R.string.loading_msg), true, false);
    
        // get ListView
        final ListView myListView = (ListView) getView().findViewById(
                    R.id.listView1);
    
        Thread thread = new Thread() {
            @Override
            public void run() {
                //load your data here (fill Adapter)!
                loadData();
    
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // fill ListView, dismiss Dialog
                        myListView.setAdapter(yourAdapterWithData);
                        dialog.dismiss();
                        }
                    });
                }
            };
    
        thread.start();
    }