Reputation: 117
I need to inflate data into parent child relation as in expandable list view but in a same card-view which is rather complicated to design.So I tried to arrange the data into a Hashmap<String,List<object>>
into key-value pair.But now not able to understand how to map the data into recyclerview adapter.
I don't want to use SectionedRecyclerViewAdapter or any third party library.
Output is coming like as shown in pic but according to map data 2 categories and 3 and 4 child should come under each category.
I have also tried this solution but it didn't work.
My map Data:
Dry Clean
---------
Punjabi Set
Blazer
Safari suit
Wash & Iron
-----------
Suit (3 pcs set)
Denim-Short
Dhoti
Waist Coat
Adapter Class:
public class OrderDetailsAdapter extends RecyclerView.Adapter<OrderDetailsAdapter.MyViewHolder> {
private HashMap<String, List<OrderDetailsModel.CartDatum>> moviesList;
Context mContext;
MyViewHolder holder1;
ProgressDialog progressDialog;
ConnectionDetector cd;
private SparseBooleanArray expandState = new SparseBooleanArray();
HashMap<String, List<OrderDetailsModel.CartDatum>> hashMap;
public OrderDetailsAdapter(HashMap<String, List<OrderDetailsModel.CartDatum>> moviesList, Context mContext) {
this.moviesList = moviesList;
this.mContext = mContext;
progressDialog = new ProgressDialog(mContext);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.setCanceledOnTouchOutside(false);
cd = new ConnectionDetector(mContext);
this.hashMap = moviesList;
for (int i = 0; i < moviesList.size(); i++) {
expandState.append(i, false);
}
}
private ObjectAnimator createRotateAnimator(final View target, final float from, final float to) {
ObjectAnimator animator = ObjectAnimator.ofFloat(target, "rotation", from, to);
animator.setDuration(300);
animator.setInterpolator(new LinearInterpolator());
return animator;
}
private void onClickButton(final LinearLayout expandableLayout, final RelativeLayout buttonLayout, final int i) {
//Simply set View to Gone if not expanded
//Not necessary but I put simple rotation on button layout
if (expandableLayout.getVisibility() == View.VISIBLE) {
createRotateAnimator(buttonLayout, 180f, 0f).start();
expandableLayout.setVisibility(View.GONE);
expandState.put(i, false);
} else {
createRotateAnimator(buttonLayout, 0f, 180f).start();
expandableLayout.setVisibility(View.VISIBLE);
expandState.put(i, true);
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tv_productname, tv_packetsize, tv_position;
AppCompatImageView iv_product;
RelativeLayout buttonLayout;
LinearLayout expandableLayout;
TextView tvCatName;
public MyViewHolder(View view) {
super(view);
tvCatName = view.findViewById(R.id.tvCatName);
tv_productname = view.findViewById(R.id.tv_productname);
iv_product = view.findViewById(R.id.iv_product);
tv_packetsize = view.findViewById(R.id.tv_packetsize);
buttonLayout = view.findViewById(R.id.button);
expandableLayout = view.findViewById(R.id.expandableLayout);
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_orderdetails, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder1 = holder;
final boolean isExpanded = expandState.get(position);
holder.expandableLayout.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
holder.buttonLayout.setRotation(expandState.get(position) ? 180f : 0f);
holder.buttonLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
onClickButton(holder.expandableLayout, holder.buttonLayout, position);
}
});
for (Map.Entry<String, List<OrderDetailsModel.CartDatum>> entry : hashMap.entrySet()) {
//System.out.println(entry.getKey()+" : "+entry.getValue());
Log.e("VAluess", entry.getKey() + " : " + entry.getValue().size());
holder.tvCatName.setText(entry.getKey());
for (int j = 0; j < entry.getValue().size(); j++) {
holder.tv_productname.setText(entry.getValue().get(j).getDressName());
try {
Picasso.with(mContext)
.load(entry.getValue().get(j).getDressPhoto())
.into(holder.iv_product, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
// holder.progressbar.setVisibility(View.GONE);
}
@Override
public void onError() {
holder.iv_product.setImageResource(R.mipmap.ic_launcher);
}
});
} catch (Exception e) {
}
}
}
}
@Override
public int getItemCount() {
return moviesList.size();
}
}
Upvotes: 1
Views: 1884
Reputation: 696
My Requirement was quite similar like yours. I have also used a Hashmap<String,<Objects>>
but my solution look little bit buggy to myself as I am inflating the child view dynamically in the adapter class which should not be the way of course but it will serve your purpose. Any suggestion or help would be appreciated to make the code better...
//Main Activity Class
public class MainActivity extends AppCompatActivity {
List<Data> listData1 = new ArrayList<>();
List<Data> listData2 = new ArrayList<>();
List<Data> listData3 = new ArrayList<>();
DataAdapter adapter;
MapAdapter mapAdapter;
Context mcontext;
AlphabetIndexFastScrollRecyclerView alphabetIndexFastScrollRecyclerView;
HashMap<String, List<Data>> listHash = new HashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mcontext = this;
listData1.add(new Data("Avik", 20.1));
listData1.add(new Data("Arnab", 21.1));
listData1.add(new Data("Anikit", 2));
listData2.add(new Data("Rajjoy", 3));
listData2.add(new Data("Sandipan", 4));
listData2.add(new Data("Arindam", 54));
listData2.add(new Data("Abhishek", 23));
listData3.add(new Data("Raju",23));
listData3.add(new Data("Nagarjuna",21));
listHash.put("Dry Wash", listData1);
listHash.put("Iron", listData2);
alphabetIndexFastScrollRecyclerView = findViewById(R.id.recyclerView);
alphabetIndexFastScrollRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
mapAdapter = new MapAdapter(mcontext, listHash);
alphabetIndexFastScrollRecyclerView.setAdapter(mapAdapter);
}
}
// Adapter Class
public class MapAdapter extends RecyclerView.Adapter<MapAdapter.MyHolder> {
HashMap<String, List<Data>> dataList;
Context context;
private SparseBooleanArray expandState = new SparseBooleanArray();
public MapAdapter(Context context, HashMap<String, List<Data>> dataList) {
this.dataList = dataList;
this.context = context;
for (int i = 0; i < dataList.size(); i++) {
expandState.append(i, false);
}
}
@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_map, null);
return new MyHolder(view);
}
@Override
public void onBindViewHolder(final MyHolder holder, final int position) {
holder.setIsRecyclable(false);
holder.textView_name.setText(getHashMapKeyFromIndex(dataList, position));
final boolean isExpanded = expandState.get(position);
holder.expandableLayout.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
Log.e("val", "" + dataList.get(getHashMapKeyFromIndex(dataList, position)).size());
//llContainer
holder.llContainer.removeAllViews();
double sum = 0;
LayoutInflater layoutInflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < dataList.get(getHashMapKeyFromIndex(dataList, position)).size(); i++) {
Log.e("VALL", dataList.get(getHashMapKeyFromIndex(dataList, position)).get(i).title);
View view = layoutInflator.inflate(R.layout.row_subcat_child, null);
TextView tv_title = view.findViewById(R.id.tv_title);
TextView tv_price = view.findViewById(R.id.tv_price);
tv_title.setText(dataList.get(getHashMapKeyFromIndex(dataList, position)).get(i).title);
tv_price.setText(String.valueOf(dataList.get(getHashMapKeyFromIndex(dataList, position)).get(i).price));
sum = sum + dataList.get(getHashMapKeyFromIndex(dataList, position)).get(i).price;
holder.llContainer.addView(view);
}
holder.textView_total.setText(""+sum);
Log.d("sum",""+sum);
holder.buttonLayout.setRotation(expandState.get(position) ? 180f : 0f);
holder.buttonLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
onClickButton(holder.expandableLayout, holder.buttonLayout, position);
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
public class MyHolder extends RecyclerView.ViewHolder {
TextView textView_name,textView_total;
LinearLayout expandableLayout, llContainer;
RelativeLayout buttonLayout;
public MyHolder(View view) {
super(view);
textView_total = view.findViewById(R.id.textView_total);
textView_name = view.findViewById(R.id.textView_name);
expandableLayout = view.findViewById(R.id.expandableLayout);
buttonLayout = view.findViewById(R.id.button);
llContainer = view.findViewById(R.id.llContainer);
}
}
public static String getHashMapKeyFromIndex(HashMap hashMap, int index) {
String key = null;
HashMap<String, Object> hs = hashMap;
int pos = 0;
for (Map.Entry<String, Object> entry : hs.entrySet()) {
if (index == pos) {
key = entry.getKey();
}
pos++;
}
return key;
}
private ObjectAnimator createRotateAnimator(final View target, final float from, final float to) {
ObjectAnimator animator = ObjectAnimator.ofFloat(target, "rotation", from, to);
animator.setDuration(300);
animator.setInterpolator(new LinearInterpolator());
return animator;
}
private void onClickButton(final LinearLayout expandableLayout, final RelativeLayout buttonLayout, final int i) {
//Simply set View to Gone if not expanded
//Not necessary but I put simple rotation on button layout
if (expandableLayout.getVisibility() == View.VISIBLE) {
createRotateAnimator(buttonLayout, 180f, 0f).start();
expandableLayout.setVisibility(View.GONE);
expandState.put(i, false);
} else {
createRotateAnimator(buttonLayout, 0f, 180f).start();
expandableLayout.setVisibility(View.VISIBLE);
expandState.put(i, true);
}
}
}
//Data Class
public class Data {
String title;
String classs;
String section;
double price;
public Data(String title, double price) {
this.title = title;
this.price = price;
}
public Data(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getClasss() {
return classs;
}
public void setClasss(String classs) {
this.classs = classs;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
}
//row_subcat_child
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4">
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"></TextView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"></TextView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"></TextView>
<TextView
android:id="@+id/tv_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"></TextView>
</LinearLayout>
</RelativeLayout>
// list_item_map
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/buttonLayout"
android:layout_width="match_parent"
android:layout_height="48dp">
<RelativeLayout
android:id="@+id/pparent"
android:layout_width="wrap_content"
android:layout_toLeftOf="@+id/button"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_toLeftOf="@+id/textView_total"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textView_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:layout_marginBottom="10dp"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
<!--My dropdown Button -->
<RelativeLayout
android:id="@+id/button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_gravity="end"
android:gravity="center">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentEnd="false"
android:layout_alignParentRight="false"
android:background="@drawable/ic_arrow_drop_down_black_24dp" />
</RelativeLayout>
</RelativeLayout>
<!--The layout below is my ExpandableLayout -->
<LinearLayout
android:id="@+id/expandableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/llContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Upvotes: 1