1

I am using several activities based on the ListActivity. All of them display information from different SQLite queries, and all of them use the ViewHolder optimization. The cursor adapter have to be specialized, and the view holder is also special for the purpose. Therefore, they are defined as private classes inside the MyListActivity definition.

Not having too much experience with Java, my question is whether the chosen approach is correct. Possibly the non-nested classes (i.e. flat, separate *.java file) is not better for reasons unknown to me.

What are the pros and cons of nested/flat approaches?

To be more specific, here is the code skeleton:

public class MyListActivity extends ListActivity
        implements LoaderManager.LoaderCallbacks<Cursor> {

    private MyCursorAdapter myAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        initLoaderAndSetListAdapter();
    }

    private static class MyViewHolder {
        public TextView code;
        public CharArrayBuffer codeBuffer = new CharArrayBuffer(20);
        ...
    }

    private class MyCursorAdapter extends CursorAdapter {

        private final LayoutInflater mInflater;
        private final int mLayout;

        public MyCursorAdapter(Context context, Cursor c, int flags) {
            super(context, c, flags);
            mLayout = R.layout.the_specific_view_for_the_list_item;
            mInflater = (LayoutInflater)
                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View v = mInflater.inflate(mLayout, parent, false);
            MyViewHolder holder = new MyViewHolder();
            holder.code = (TextView) v.findViewById(R.id.code);
            v.setTag(holder);
            return v;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            MyViewHolder holder = (MyViewHolder) view.getTag();
            cursor.copyStringToBuffer(1, holder.codeBuffer);  // COLUMN_CODE
            ...
            holder.code.setText(holder.codeBuffer.data, 0, holder.codeBuffer.sizeCopied);
            ...
        }
    }

    private void initLoaderAndSetListAdapter() {
        getLoaderManager().initLoader(0, null, this);
        myAdapter = new MyCursorAdapter(this, null, 0);
        setListAdapter(myAdapter);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Uri uri = ... set the uri based on situation... ;
        String[] projection = { ... };
        CursorLoader cursorLoader = new CursorLoader(this,
                uri, projection,
                null, null,
                orderingInfo);
        return cursorLoader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        myAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        myAdapter.swapCursor(null);
    }
}

The question is specific to the described situation that I meet repeatedly. Please, do not consider it as general nested classes or not.

1

Oracle says:

Why Use Nested Classes?

There are several compelling reasons for using nested classes, among them:

  1. It is a way of logically grouping classes that are only used in one place.
  2. It increases encapsulation.
  3. Nested classes can lead to more readable and maintainable code.

Logical grouping of classes — If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

Increased encapsulation — Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

Now apply those criteria to your proposed use of nested classes. Do the benefits justify the additional complexity of class nesting?

Nested classes can only be used inside their outer class, so they need to prove their worth within the class, since they're not usable anywhere else. The overall question is this: can MyViewHolder be useful anywhere else in the program, or is it only ever going to be useful in MyListActivity?

  • Thanks, but it is exactly what I am asking :) Do the benefits justify the additional complexity of class nesting? I would not ask if I were more experienced in Java/Android. – pepr Aug 20 '13 at 6:45
  • @pepr: I've never found a compelling reason to use an internal class, but I use C#, and it might be a little different in that regard. – Robert Harvey Aug 20 '13 at 15:50
  • Sorry for being THAT late to accept. – pepr Aug 18 '14 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.