Question

Documents say:

When the content for your layout is dynamic or not pre-determined, you can use a layout that subclasses AdapterView to populate the layout with views at runtime. A subclass of the AdapterView class uses an Adapter to bind data to its layout.

But most of tutorials are in about ListView,GridView,Spinner and Gallery.

I'm looking to extend a subclass directly from AdapterView. I have to create a custom view that it's content is dependent to an adapter.

How can I do this, and what methods must be overridden?

Was it helpful?

Solution

First, you should be absolutely sure that AdapterView is what you want, because not all "dynamic or not pre-determined" views can be implement via AdapterView. Sometimes you'd better create your view extending ViewGroup.

if you want to use AdapterView, take a look at this really nice example. There are a lot of custom views with adapter on GitHub. Check out this one (extends ViewGroup).

OTHER TIPS

This may not be a total answer to your question but i am showing you most probably a starting point or pointer which can guide you:

Sony Developer Tutorials - 3D ListView

ListView extends AbsListView which in turn extends AdapterView<ListAdapter>. So if you absolutely must implement such a custom view from scratch, you could have a look at the source code of those classes:

But beware, that's quite a task. Perhaps it may be sufficient to use one of the existing classes and tweak the look.

Deriving from AdapterView can work, but it may not be as beneficial as you hope. Some of the infrastructure provided by AdapterView is package-private, meaning we don't have access to it.

For example, AdapterView manages the selected item index for AbsListView and ListView. However, because methods like setNextSelectedPositionInt(int position) (which is the only path to setting mNextSelectedPosition) are package-private, we can't get to them. AbsListView and ListView can get to them because they're in the same package, but we can't.

(If you dig into the AdapterView source you'll find that setNextSelectedPositionInt() is called from handleDataChanged(). Unfortunately handleDataChanged() is also package-private and is _not_called from anywhere else within AdapterView that could be leveraged to enable setting position.)

That means that if you need to manage selected position, you'll need to recreate that infrastructure in your derived class (or you'll need to derive from ListView or AbsListView...though I suspect you'll run into similar problems deriving from AbsListView). It also means that any AdapterView functionality that revolves around item selection likely won't be fully operational.

You could create something like this :

public class SampleAdapter extends BaseAdapter {

public SampleAdapter() {
  // Some constructor
}

public int getCount() {
  return count; // Could also be a constant. This indicates the # of times the getView gets invoked.
}

public Object getItem(int position) {
    return position; // Returns the position of the current item in the iteration
}

public long getItemId(int position) {
  return GridView.INVALID_ROW_ID;
}

public View getView(int position, View convertView, ViewGroup parent) {
  View view = null;

  view = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.some_layout, null);
  view.setLayoutParams(new GridView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
view.setBackgroungColor(Color.RED);

  return view;
}

}

And this could be invoked like :

GridView sampleView = (GridView) linearLayout.findViewById(R.id.sample_layout);
sampleView.setAdapter(new SampleAdapter());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top