title: How to display an empty view, progress view and datas in a ListView?
body: <p>This is mainly a conceptual question. I am using a ListFragment in my Activity. Its list must display one of these information:</p>
  
  <ul>
  <li>A list of items</li>
  <li>An empty view if there is no items</li>
  <li>A "loading" view for when the datas are loaded from the database</li>
  </ul>
  
  <p>The empty view is managed automatically by the framework because my ListFragment's on onCreateView is creating a custom view like this:</p>
  
  <pre><code>@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);
  }
  </code></pre>
  
  <p>The Layout of kanji_list is this one:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" &gt;
  
  &lt;ListView android:id="@id/android:list"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:listSelector="@android:color/transparent" /&gt;
  
      &lt;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"/&gt;
  </code></pre>
  
  <p></p>
  
  <p>The datas are stored in a SQLite database that is embedded in my application. When the application wants to update to ListView, a custom Loader is used to query the database and return a Cursor to the ListFragment. I use a custom Loader and not the CursorLoader because I don't want to create a ContentProvider.</p>
  
  <p>So, <strong>what I would like to do</strong> is: <em>when the application start a query of the datas from the database, the "loading" view will be shown, showing a progress picture and a text saying something like "Getting datas". Then, when the Loader finishes its job, I want to display the queried datas in the ListView, or display the "empty" view if there is no data.</em></p>
  
  <p>I don't want to use a ProgressDialog for some reasons. So my question is: how to provide the "loading" view? Here are my first, rough ideas:</p>
  
  <ol>
  <li>Replace the ListView by a custom view during the load of the datas and show the List when the Loader finishes its job</li>
  </ol>
  
  <p>or</p>
  
  <ol>
  <li>Use one Adapter for displaying the datas</li>
  <li>Use another Adapter containing only one item that is the "loading" view</li>
  <li>Set the right Adapter at the right time (when the Loader start its job: myList.setAdapter(mLoadingAdapter), when the Loader finishes its job: myList.setAdapter(mDataAdapter))</li>
  </ol>
  
  <p>Any other ideas? Do you have any "good practice" hint to give to me in order to achieve that?</p>
  
  <hr>
  
  <p><strong>I found the solution, thank you Kasra Rahjerdi and Harikris!</strong>
  Here is how I did it:</p>
  
  <p>First, create a layout file for the ListView, empty view and the "loading" view:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" &gt;
  
      &lt;LinearLayout android:id="@+id/listcontainer"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          &gt;
  
          &lt;ListView android:id="@id/android:list"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:listSelector="@android:color/transparent"
              /&gt;
  
          &lt;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"/&gt;
      &lt;/LinearLayout&gt;
  
      &lt;ch.shibastudio.kanjinotepad.customviews.LoadingView android:id="@+id/loading"
      android:layout_height="match_parent"
      android:layout_width="match_parent"
      android:visibility="gone"
      /&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>It is very important to create a container (here <em>listContainer</em>) for the ListView <strong>and</strong> the empty view. I tried to set the Visibility of the ListView to GONE and it automatically set the Visibility of the empty view to Visible. Looks like there is some internal code doing that for the ListView, so the solution was to put them in a container and showing/hiding it completely.</p>
  
  <p>So basically, the idea is: When the datas are loading, I want to show the loading view, for that, I hide the ListView container by putting its Visibility to GONE (if I put the Visibility to INVISIBLE, it keeps the size of the list in the View, using GONE is like removing it completely and thus, the "loading" view can take all the screen) and showing the the "loading" view by putting its visibility to VISIBLE.</p>
  
  <p>In my ListFragment, I got the references of these views like this:</p>
  
  <pre><code>@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;
  }
  </code></pre>
  
  <p>And I show/hide the "loading" view by calling this method:</p>
  
  <pre><code>private void setLoadingViewVisible(boolean visible){
      if(null != mLoadingView &amp;&amp; null != mListContainer){
          mListContainer.setVisibility(visible ? View.GONE : View.VISIBLE);
          mLoadingView.setVisibility(visible ? View.VISIBLE : View.GONE);
      }
  }
  </code></pre>