2

I have a RecyclerView containing cards related to a user's activity goals. In part of each card I want to inflate a different fragment, e.g. goal 1 might be a pie chart while goal 2 might be a line chart. Below is my code, the problem I am having is that currently the fragment is ever only inflated in the first item in the list.

Row layout

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvLastSync"
        android:textSize="10dip"
        android:textColor="@android:color/darker_gray"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Last updated: 12:00">
    </TextView>

    <!--
    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/today_pie_chart"
        android:layout_width="wrap_content"
        android:layout_height="250dp"
        android:layout_alignParentLeft="true"
        android:layout_marginTop="76dp"
        android:background="@android:color/transparent"
        android:layout_below="@+id/tvLastSync"/> -->

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fragment_chart_container"
        android:layout_width="wrap_content"
        android:layout_height="250dp"
        android:layout_marginTop="76dp"
        android:background="@android:color/transparent"
        android:layout_below="@+id/tvLastSync"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvDetails"
        android:textSize="30dip"
        android:textColor="@android:color/darker_gray"
        android:paddingTop="5dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="9999/10000">
    </TextView>

    <TextView
        android:layout_width="150dip"
        android:layout_height="wrap_content"
        android:id="@+id/tvInfo"
        android:textSize="20dip"
        android:textColor="@android:color/darker_gray"
        android:layout_alignParentRight="true"
        android:text="Some additional information"
        android:layout_below="@+id/tvDetails">
    </TextView>


</RelativeLayout>

Goal progress adapter
public class GoalProgressAdapter extends RecyclerView.Adapter<GoalProgressAdapter.ViewHolder> {

    private ArrayList<GoalStruct> goalList;
    private int rowLayout;
    private Context mContext;
    private LoadDataHelper loadDataHelper;

    public GoalProgressAdapter(ArrayList<GoalStruct> pGoalList, int pRowLayout, Context pContext){
        this.goalList = pGoalList;
        this.rowLayout = pRowLayout;
        this.mContext = pContext;
        this.loadDataHelper = new LoadDataHelper(mContext);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false);
        return new ViewHolder(v);
    }

    @Override
    public int getItemCount() {
        return goalList == null ? 0 : goalList.size();
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        Goal g = goalList.get(i).goal;

        // todo populate info with some text based on progress - e.g. lets get started
        viewHolder.tvInfo.setText(" a motivational message ");

        // when the adapter has been bound load data related to goal
        loadDataHelper.getDataFromCache(false, g, viewHolder.tvLastSync, viewHolder.tvDetails, viewHolder.chartHolder);

    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
        public TextView tvLastSync;
        public FrameLayout chartHolder;
        public  TextView tvDetails;
        public  TextView tvInfo;

        public ViewHolder(View itemView){
            super(itemView);
            tvLastSync = (TextView) itemView.findViewById(R.id.tvLastSync);
            chartHolder = (FrameLayout) itemView.findViewById(R.id.fragment_chart_container);
            tvDetails = (TextView) itemView.findViewById(R.id.tvDetails);
            tvInfo = (TextView) itemView.findViewById(R.id.tvInfo);
        }

    }



}

relevant parts of LoadDataHelper

FrameLayout fragmentContainer;    
    if (chartType == 1){
                // if using a pie chart
                 xVals.add("label 1");
                 xVals.add("label 2");
                 //yVals.add(new Entry(Float.parseFloat(goal.getTargetMeasurement()),0));
                 //yVals.add(new Entry(Float.parseFloat(es.value),1));
                 yVals.add(goal.getTargetMeasurement());
                 yVals.add(es.value);

                 Fragment_PieChart fpc = new Fragment_PieChart();
                 Bundle args = new Bundle();
                 args.putStringArrayList(Values.keyPieAxisLabels, xVals);
                 args.putStringArrayList(Values.keyPieAxisValues, yVals);
                 //args.putInt(Values.keyPieChart, fragmentContainer);
                 fpc.setArguments(args);

                 FragmentManager fm = ((Activity) mContext).getFragmentManager();
                 FragmentTransaction ft = fm.beginTransaction();
                 ft.add(fragmentContainer.getId(), fpc);
                 Log.d("LoadDataHelper: ", "Performing frag tran in " + fragmentContainer.getId());
                 ft.commit();

            }

Part of Fragment_PieChart

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_pie_chart, container, false);
        Log.d("Test", "Inflating Fragment_PieChart");

        Bundle b = getArguments();
        xVals = b.getStringArrayList(Values.keyPieAxisLabels);
        yVals = b.getStringArrayList(Values.keyPieAxisValues);

        pc = (PieChart) v.findViewById(R.id.today_pie_chart);

        drawPieChart(xVals, yVals);

        return v;
    }

Any help would be much appreciated :-)

tjp
  • 203
  • 1
  • 4
  • 9
  • 1
    most important part of the class name is? ... **Recycler** ... so solution is to add every type of chart in every item and hide em or show only the one you needs ... or (better) read about getItemViewType(int position) of adapter ... but of course the type should be know at the time of inflating (onCreateViewHolder) .... (like Goal object) ... in second solution you have to have different layouts for each type – Selvin Jul 06 '15 at 14:55
  • 1
    Hi Selvin, many thanks for your suggestions. In the end I avoided using fragments within the RecyclerView and implemented getItemViewType(int position) with different layouts for each type as you suggested, cheers! – tjp Jul 07 '15 at 10:18

2 Answers2

2

Consider to use getItemViewType(int position) of RecyclerView.Adapter. Example: How to create RecyclerView with multiple view type? . It worked for me. I hope this helps.

Community
  • 1
  • 1
Victor Gomes
  • 463
  • 6
  • 15
0

You need to use getItemViewType() method which available in RecyclerView.Adapter .I found this link for me ,it helps me lots.

Rahul Chaube
  • 334
  • 3
  • 11