avik
avik

Reputation: 117

Mapping a map data into Recyclerview Adapter in a same cardview without using any third party

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();
    }
}

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

Upvotes: 1

Views: 1884

Answers (1)

androholic
androholic

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>

enter image description here

Upvotes: 1

Related Questions