Anshul
Anshul

Reputation: 7964

How do I show emptyview in Listview in case my adapter is null?

I wanted to show a Button in my Listview in case I dont have data to fill in the list through custom Array adapter.Everything works fine in case I have data and my listview get filled with data items, but if i have no data item to show the listview should display the LinearLayout with id "@android:id/empty" but it never shows this up and my application got crash at this stage.In my FavoriteStudents.java class file I have an AsyncTask defined.In doInBackground method I check if favorite file exists in my phone internal memory to create adapter for listview, if not then stop AsyncTask and show list view with just a buttom.After it return from the doInBackground method it crashes and shows me this error:

10-16 16:06:37.568: E/WindowManager(274): Activity com.example.hellogridview.FavoriteStudets has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44bfea80 that was originally added here
10-16 16:06:37.568: E/WindowManager(274): android.view.WindowLeaked: Activity com.example.hellogridview.FavoriteStudents has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44bfea80 that was originally added here
10-16 16:06:37.568: E/WindowManager(274):   at android.view.ViewRoot.<init>(ViewRoot.java:227)
10-16 16:06:37.568: E/WindowManager(274):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
10-16 16:06:37.568: E/WindowManager(274):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
10-16 16:06:37.568: E/WindowManager(274):   at android.view.Window$LocalWindowManager.addView(Window.java:424)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.Dialog.show(Dialog.java:239)
10-16 16:06:37.568: E/WindowManager(274):   at com.example.hellogridview.FavoriteStudents$readingFavFileTask.onPreExecute(FavoriteStudents.java:50)
10-16 16:06:37.568: E/WindowManager(274):   at android.os.AsyncTask.execute(AsyncTask.java:391)
10-16 16:06:37.568: E/WindowManager(274):   at com.example.hellogridview.FavoriteStudents.onCreate(FavoriteStudents.java:34)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.ActivityThread.access$2200(ActivityThread.java:119)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
10-16 16:06:37.568: E/WindowManager(274):   at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 16:06:37.568: E/WindowManager(274):   at android.os.Looper.loop(Looper.java:123)
10-16 16:06:37.568: E/WindowManager(274):   at android.app.ActivityThread.main(ActivityThread.java:4363)
10-16 16:06:37.568: E/WindowManager(274):   at java.lang.reflect.Method.invokeNative(Native Method)
10-16 16:06:37.568: E/WindowManager(274):   at java.lang.reflect.Method.invoke(Method.java:521)
10-16 16:06:37.568: E/WindowManager(274):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-16 16:06:37.568: E/WindowManager(274):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-16 16:06:37.568: E/WindowManager(274):   at dalvik.system.NativeStart.main(Native Method)

My xml file

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

    <ListView
        android:id="@+id/studentsList"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:divider="#b5b5b5"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/student_list_selector" >
    </ListView>

    <!-- empty view -->

    <LinearLayout
        android:id="@android:id/empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/addStudents"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Add Students" >
        </Button>
    </LinearLayout>

</LinearLayout>

My Student adapter

public class StudentsAdapter extends ArrayAdapter<Students> {

    private Context context;
    ImageDownloaderNew imageDownloader;
    ArrayList<Students> students;
    Songs studentsTemp = null;
    int targetWidth = 70;
    int targetHeight = 110;

    public StudentsAdapter (Context context, int textViewResourceId,
            ArrayList<Students> students) {
        super(context, textViewResourceId, songs);
        // TODO Auto-generated constructor stub
        this.context = context;
        this.students= students;
        imageDownloader = new ImageDownloaderNew();
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub

        return students.size();
    }

    @Override
    public Students getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    static class ViewHolder {
        protected TextView studentTitle;
        protected RatingBar studentRating;
        protected TextView studentViews;
        protected ImageView studentImage;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        //My getView code goes here.I have not pasted here
        return convertView;

    }

}

Now FavoriteStudents.java class file

public class FavoriteStudents extends SherlockActivity {

    ListView list;
    StudentsAdapter adapter;
    ArrayList<Students> studentsListArray = new ArrayList<Students>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.students_list);

        new readingFavFileTask().execute(UtilityFuctions.FAV_STUDENTS_FILE_NAME);
    }

    private class readingFavFileTask extends AsyncTask<String, Void, String> {

        ProgressDialog m_dialog = new ProgressDialog(FavoriteStudents.this);

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            // initialize the dialog
            m_dialog.setTitle("Loading...");
            m_dialog.setMessage("Please wait while loading...");
            m_dialog.setIndeterminate(true);
            m_dialog.setCancelable(true);
            m_dialog.show();

        }

        @Override
        protected String doInBackground(String... params) {

            if (!UtilityFuctions.isFileExists(getApplicationContext(),
                    params[0])) {
                // favorite file does not exists
                finish();
                return "fileDoesNotExists";
            }else{
            StudentsListArray = UtilityFuctions.readFavJSONFile(
                    getApplicationContext(), params[0]);
            if (isCancelled())
                finish();
            return null;}
        }

        @Override
        protected void onPostExecute(String result) {
            list = (ListView) findViewById(R.id.studentsList);
            if (result.equals("fileDoesNotExists")) {
                adapter = new StudentsAdapter(FavoriteStudents.this, 1,
                        studentsListArray);
                list.setAdapter(adapter);
                            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            View myView = inflater.inflate(R.layout.empty_view, null);
                            list.setEmptyView(myView);
                            m_dialog.dismiss();

            } else {
                // Creating a StudentsAdapter and setting it on listview

                adapter = new StudentsAdapter(FavoriteStudents.this, 1,
                        studentsListArray);
                list.setAdapter(adapter);
                m_dialog.dismiss();

                // Click event for single list row
                list.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                                      //onItemClick code goes here

                    }
                });
            }
        }
    }

}

EDIT: @Rolf Smith answer is correct.But The main problem is I am calling finish() in my doInBackground() method which is killing my activity and not showing me the emptyView.So i just remove finish() and everything working perfectly. Thanks EveryOne

Upvotes: 0

Views: 3101

Answers (1)

Rolf ツ
Rolf ツ

Reputation: 8781

The empty view (using the android empty id) only works when you use a ListActivity or ListFragment, in this case you have to do the logic your self using the setEmptyView() method.

ListView.setEmptyView()

and the crash you got is probably because the dialog you have shown is not dismissed when your activity closes. So for example in the onPause method call the dismiss method from the dialog you have shown.

Rolf

Edit see comments:

The empty view will be shown with View.GONE and View.VISIBLE this means that you don't need to add it your self etc.

Take a look at this code: And take a good look at the onCreate method.

import android.widget.ListView;

public class FavoriteStudents extends SherlockActivity {

    ListView list;
    StudentsAdapter adapter;
    ArrayList<Students> studentsListArray = new ArrayList<Students>();
    private ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.students_list);
        list = (ListView) findViewById(R.id.studentsList);

        View empty = findViewById(R.id.empty_view);
        list.setEmptyView(empty);

        new readingFavFileTask().execute(UtilityFuctions.FAV_STUDENTS_FILE_NAME);
    }

    private class readingFavFileTask extends AsyncTask<String, Void, String> {

        ProgressDialog m_dialog = new ProgressDialog(FavoriteStudents.this);

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            // initialize the dialog
            m_dialog.setTitle("Loading...");
            m_dialog.setMessage("Please wait while loading...");
            m_dialog.setIndeterminate(true);
            m_dialog.setCancelable(true);
            m_dialog.show();

        }

        @Override
        protected String doInBackground(String... params) {

            if (!UtilityFuctions.isFileExists(getApplicationContext(),
                    params[0])) {
                // favorite file does not exists
                finish();
                return "fileDoesNotExists";
            }else{
            StudentsListArray = UtilityFuctions.readFavJSONFile(
                    getApplicationContext(), params[0]);
            if (isCancelled())
                finish();
            return null;}
        }

        @Override
        protected void onPostExecute(String result) {
            if (result.equals("fileDoesNotExists")) {
                adapter = new StudentsAdapter(FavoriteStudents.this, 1, studentsListArray);
                list.setAdapter(adapter);
                m_dialog.dismiss();

            } else {
                // Creating a StudentsAdapter and setting it on listview

                adapter = new StudentsAdapter(FavoriteStudents.this, 1,
                        studentsListArray);
                list.setAdapter(adapter);
                m_dialog.dismiss();

                // Click event for single list row
                list.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                                      //onItemClick code goes here

                    }
                });
            }
        }
    }

}

Upvotes: 6

Related Questions