Reputation: 525
my problem is - how to create custom list view with not just repeating one custom view, but like in Instagram or other app where list include other views in it, which it looks like scroll view with list view android other views in it, but Roman Guy says "List View in a Scroll view is a very poor way", and I'm agreed with it, don't believe which is Google use this way...
What are the best way to achieve this thing with ListView or Recycler View
Upvotes: 3
Views: 2586
Reputation: 105
You are looking for different View types. It's possible with using these
GetViewTypeCount()
this is an overridable method which returns how many view type you have in your listview-recycleview.
getItemViewType(int pos)
get which item view type should return at the given position
For example if you want to add a different view in every 10 item, and there is only 2 type of views, you should use a code like this:
@Override
public int getItemViewType(int position){
if (position % 10 == 0)
return SECOND_ITEM;
return FIRST_ITEM;
}
@Override
public int getViewTypeCount() {
return 2;
}
And at the getView()
function you can handle it with a switch-case or if-else structure like this:
switch (getItemViewType(cursor.getPosition())) {
case SECOND_ITEM:
//something to do
break;
default:
//something to do
}
You might want to use 2 different layout file to inflate in the switch-case statement above. However, if the layouts of both items are not different that much, I recommend to create just 1 layout, and make views inside it visible and gone according to item you want to get.
Oh and in case you don't know where to use them, you use them at your adapter class. The functions may vary as which kind of adapter you use however, they all work with the same logic.
And finally, I recommend you to use recyclerview. It is just a bit harder to implement than listview but it is a great substitution of listview which is more powerful and flexible. You can do a research for it.
Here is how you can achieve this like instagram, facebook etc. : You inflate a scrollable view at the given positions.
I hope the answer helps.
As always, Have a nice day.
Upvotes: 2
Reputation: 96
To achieve that UI, you must define multiple view types for your Listview or Recyclerview; a very similar question has been answered here.
In your example, you will have two view types:
<Horizontal Scroll>
which is an embedded horizontal Recyclerview/Listview.<View>
which is a view type that you have defined.There are many tutorials on this concept. I would recommend you to use Recyclerview in your implementation due to its advantages over Listview.
Upvotes: 3
Reputation: 739
Hey this is how your main fragment will look like :
package com.leoneo.stackoverflow;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.soulpatch.stackoverflow.R;
import java.util.ArrayList;
public class RecyclerViewExample extends Fragment {
private ArrayList<Object> mValues = new ArrayList<>();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final RecyclerView recyclerView = inflater.inflate(R.layout.recycler_view_example, container, false);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
final MultpleItemAdapter adapter = new MultpleItemAdapter(mValues);
recyclerView.setAdapter(adapter);
return recyclerView;
}
}
And here's your adapter code.
package com.leoneo.stackoverflow;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.soulpatch.stackoverflow.R;
import java.util.ArrayList;
public class MultpleItemAdapter extends RecyclerView.Adapter<MultpleItemAdapter.ViewHolder> {
private ArrayList<Object> mValues = new ArrayList<>();
public MultpleItemAdapter(ArrayList<Object> values) {
mValues = values;
}
enum ItemType {
TYPE_A,
TYPE_B;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 1:
//Inflate Type A layout
final LinearLayout linearLayoutA = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_a, parent, false);
//And pass the view to the ViewHolder
return new ViewHolder(linearLayoutA);
break;
case 2:
//Inflate Type B layout
final LinearLayout linearLayoutB = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_b, parent, false)
//And pass the view to the ViewHolder
return new ViewHolder(linearLayoutB);
break;
}
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case 1:
final TypeA typeA = (TypeA) mValues.get(position);
//Deal with the views that you defined for LinearLayout A
break;
case 2:
final TypeB typeB = (TypeB) mValues.get(position);
//Deal with the views that you defined for LinearLayout B
break;
}
}
@Override
public int getItemCount() {
return mValues.size();
}
@Override
public int getItemViewType(int position) {
final Object obj = mValues.get(position);
if (obj instanceof TypeA) {
return ItemType.TYPE_A.ordinal();
} else if (obj instanceof TypeB) {
return ItemType.TYPE_B.ordinal();
}
return super.getItemViewType(position);
}
static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
//Class that I want to be displayed in a CardView
private class TypeA {
}
//Class that I want to be displayed in a a LinearLayout
private class TypeB {
}
}
You can have as many classes as you want like TypeA
and TypeB
and add types to ItemType
class as well accordingly.
Rest should be pretty self explanatory assuming you've worked with RecyclerViews before.
Upvotes: 2