1

I'm trying to create a UI similar to Google Keep. I know how to create a staggered View using a Recycler View. If i click a specific Card. Then it has to open a activity.

I can achieve this using onclick method.

This same scenario happens in atleast 5 different Activities in my App.

My question is that

  1. Can I use this single Adapter in all those 5 places ?

    1. If yes, where should i place the onclick actions ?

    2. If no, How can I Create a staggered layout like Keep?

Thanks in Advance!

Community
  • 1
  • 1
Arulnadhan
  • 923
  • 4
  • 17
  • 46
  • I'm confused at where you're getting stuck. The link you provided shows exactly how to do what it is you want to do. So maybe the question is unclear. – NoChinDeluxe Dec 10 '15 at 17:08
  • 1
    If i use the Onclick method in my Adapter. It works. Then for another activity i have to create another adapter. So it takes 5 Adapter & more. Is this a Good Practice ? – Arulnadhan Dec 10 '15 at 17:29
  • If it's the same data you gonna represent in all five activities then you can user same adapter. But why do you do that. Instead you can user single activity and have buttons to change the view. – cgr Dec 10 '15 at 18:02
  • @user3467240 - It is definitely fine to have 5 adapters for 5 Activities if they all use separate data and UI components. You could create one BaseAdapter class that supplies different adapter objects for various activities if the data was uniform enough across those activities. You would just pass the data List in through the constructor or whatever, but don't feel bad about creating 5 separate adapters as well. I'll supply some code below if you need help understanding how to do this. – NoChinDeluxe Dec 10 '15 at 18:49
  • @drschultz Those 5 Activities use separate data & redirects to different Activities. Just show me some code. so that i can understand better. – Arulnadhan Dec 11 '15 at 04:30
  • @user3467240 you can use an abstract `Interface` in your adapter and implement its method in your Activity and provide necessary definition in activity itself. – Vipul Asri Dec 11 '15 at 16:14

1 Answers1

-1

(See application for RecyclerView below in edits)

Like I mentioned in my comment, it's certainly fine to have separate adapters for all your Activities which use different data and views. As your app data and layouts get more complex, so does your code...that's just the way it is.

But if some of your Activities used similar data in their ListViews -- maybe, for example, two TextViews and an ImageButton -- you could save some effort by defining a single adapter that can be used for multiple Activities. You would then instantiate separate objects for each Activity, similar to the way you would create several ArrayAdapter<String> objects to populate multiple ListViews.

The BaseAdapter is a great class to extend when writing a custom adapter. It's flexible and allows you complete control over the data that's getting shown in your ListView. Here's a minimal example:

public class CustomBaseAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<String> listData;

    public CustomBaseAdapter(Context context, ArrayList<String> listData) {
        this.context = context;
        this.listData = listData;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.your_list_item_layout, parent, false);

            //populate the view with your data -- some examples...
            TextView textData = (TextView) convertView.findViewById(R.id.yourTextView);
            textData.setText(listData.get(position));

            ImageButton button = (ImageButton) convertView.findViewById(R.id.yourImageButton);
            button.setOnClickListener(new View.OnClickListener() {
                //...
                //...
            });
        }

        return convertView;
    }

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

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

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

So the key part of this code is obviously the getView() method, which is called every time the ListView needs some data to display. For efficiency, views are stored in something called a convertView so they may be re-used and not have to be inflated every time a view appears on the screen.

So what we do in getView() is first find out if the convertView exists. If it does, we just pass that back to the calling ListView because everything should already be instantiated and ready to go. If the convertView is null, it means the data hasn't been instantiated (or needs to be re-instantiated for whatever reason), and so we inflate a brand new view and populate it with our data.

So in the case of this example adapter above, if several of your Activities all displayed a single list of Strings, you could reuse this adapter for each one, passing in a different ArrayList<String> through the constructor each time you created a new object. But obviously you could pass in more than just Strings if you had more data to show. The level of complexity is up to you. And if the difference among your Activities was too great, I would just create custom versions of this class for all of them and just instantiate them and populate them however you'd like. It will keep all your data very organized and encapsulated.

Hope this helps! Feel free to ask questions for more clarification if you need it.


EDIT IN RESPONSE TO COMMENTS

Since you are using a RecyclerView instead of just plain ListViews (which I, for some reason, totally forgot) you could still do something very similar using a RecyclerView.Adapter<YourViewHolder> instead. The difference would be that instead of inflating the views in a getView() method, they are inflated inside your custom ViewHolder, which I assume you already have. The code might look something like this:

public class CustomRecyclerViewAdapter extends RecyclerView.Adapter<StringViewHolder> {

    private final List<String> items;

    public CustomRecyclerViewAdapter(ArrayList<String> items) {
        this.items = items;
    }

    @Override
    public StringViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //So instead of inflating the views here or in a getView() like in 
        //in the BaseAdapter, you would instead inflate them in your custom
        //ViewHolder.
        return new StringViewHolder(parent);
    }

    @Override
    public void onBindViewHolder(StringViewHolder holder, int position) {
        holder.setModel(items.get(position));
    }

    @Override
    public long getItemId(int position) {
        return items.get(position).hashCode();
    }

    @Override
    public int getItemCount() {
        return items.size();
    }
}
NoChinDeluxe
  • 3,446
  • 1
  • 16
  • 29
  • Question specifies use of `Recycler View` and you are answering with respect to `List View`. Please be careful while answering. – Vipul Asri Dec 11 '15 at 16:11
  • @VipulAsri -- Oops, yes you are right. I was more after trying to show how to use custom adapters, and BaseAdapter is one of the simpler ones. But you're right, it should be tailored for RecyclerView. I'll make some edits when I get the chance. – NoChinDeluxe Dec 11 '15 at 16:17