3

I am trying to replicate this Google Now card interface. I'm not worried about the feel of the cards but I'm more concerned with how the view is built.

Google Now Cards

I was thinking of using an adapter which returns different layouts corresponding to the row. But as you can see both views contain information which does not relate to one another.

Is it possible to have a ListView with different row adapters?

Or how could I achieve this using a custom view?

AndroidEnthusiast
  • 6,557
  • 10
  • 42
  • 56
  • One listview and one Custom adapter that inflates different views(xml) based on the case is the best way forward. – Aditya Kushwaha Dec 18 '13 at 11:29
  • yupp u have to do it like this way only inflate different xmls – Shubham Dec 18 '13 at 11:30
  • custom views can solve it and no you can't have multiple adapters for a single view. it will replace the other adapters in case. – KaHeL Dec 18 '13 at 11:31
  • @KaHeL "custom views can solve it" , how? do you have any existing examples that tackle this kind of thing? – AndroidEnthusiast Dec 18 '13 at 11:59
  • it's more like what the answers says below. inflate the view then pass it on the adapter itself. returning the whole view as it's row modified based on its the position. That can be done but it will take a lot of work. I'll post it as my answer. – KaHeL Dec 18 '13 at 13:01

2 Answers2

3

You'll want to do this using a single adapter and inflating different views based on the position in the list. A good answer to this question is here:

Android ListView with different layouts for each row

Community
  • 1
  • 1
Dreagen
  • 1,733
  • 16
  • 21
  • How do you use a single adapter for different types of information? Lets say i'm using a "sports" object to inflate the top card and a "weather" object to inflate the bottom card, how will that work in regards to the adapter? This is my main problem – AndroidEnthusiast Dec 18 '13 at 11:53
  • I have never done exactly this. But at a guess you might want to pass 2 datasources into your custom adapter using its constructor and then, you can just get the data from the whichever datasource you need based on which layout your are inflating. You may have to manipulate the position variable in your getView method in order to get the correct item out of each datasource but I don't think that should be much of a problem – Dreagen Dec 18 '13 at 12:00
0

First you need to create a CustomAdapter for this:

public class CustomAdapter extends BaseAdapter {
    ArrayList<View> views;
    Context context;

    public CustomAdapter(Context context, ArrayList<View> views){
        this.views = views;
        this.context = context;
    }

    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public Object getItem(int i) {
        return i;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View rowView = views.get(i);
        /*set the views of the rowView here but take note use try catch since you can't be sure if the view will be present or not this is the part where I do not advice it to have different custom views per row but it's all yours to do your tricks*/

        return rowView;
    }
}

And to use it here's my sample method on create:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);

        ArrayList<View> views = new ArrayList<View>();

        CustomAdapter adapter = new CustomAdapter(MainActivity.this,views);
        ListView custom_list = (ListView)findViewById(R.id.list_custom);
        custom_list.setAdapter(adapter);

        LayoutInflater inflater = (LayoutInflater)   getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view1 = inflater.inflate(R.layout.view1, null);
        View view2 = inflater.inflate(R.layout.view2, null);

        views.add(view1);
        views.add(view2);
        adapter.notifyDataSetChanged();
}

Do your workaround if there's a need but basically this is just it. Inflate the views, pass it on your arrayList then set it on your listView.

KaHeL
  • 4,301
  • 16
  • 54
  • 78