Home > Mobile >  How to create Recyclerview game time line events
How to create Recyclerview game time line events

Time:06-27

I am developing a Game fans app. I want to create a layout given below

enter image description here

I have great experience in making custom recycelerviews with multiple LAYOUT_VIEW_TYPES.

My question is this the best way to create that recyclerview or I can do this in more easyway

CodePudding user response:

Yes the best way to achieve that result is by creating a recyclerview with multiple layouts and I think that it's the only way if you are using xml.

But this could be a lot easier if you make it using jetpack compose no need for recycler view or adapter anymore with compose and you can make any custom layout that you want.

CodePudding user response:

Phew... Finally I did it with Recyclerview custom layout items left and right.

Sharing my work.

here is my layout_item_time_line_left.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".livescore.TimeLineFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@ id/constraintLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="5dp"
        android:background="@drawable/rounded_corner_time_line_item_bg"
        android:padding="10dp"
        app:layout_constraintEnd_toStartOf="@ id/txtPlayerName2"
        app:layout_constraintTop_toTopOf="parent">

        <com.mikhaellopez.circularimageview.CircularImageView
            android:id="@ id/imgPlayerImage"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:src="@drawable/img_upload_profile"
            app:border_color="@color/white"
            app:civ_border_width="1dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:selector_stroke_color="@color/white" />

        <TextView
            android:id="@ id/txtPlayerName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_marginStart="5dp"
            android:gravity="center_horizontal"
            android:text="Neymar"
            android:textColor="#66666a"
            android:textSize="12sp"
            app:layout_constraintStart_toEndOf="@ id/imgPlayerImage"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@ id/txtEventName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_marginStart="5dp"
            android:gravity="center_horizontal"
            android:text="Goal"
            android:textColor="@color/txt_color_live_score"
            android:textSize="12sp"
            app:layout_constraintStart_toEndOf="@ id/imgPlayerImage"
            app:layout_constraintTop_toBottomOf="@ id/txtPlayerName" />

        <com.mikhaellopez.circularimageview.CircularImageView
            android:id="@ id/imgEventImage"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:layout_marginStart="4dp"
            android:layout_marginTop="2dp"
            android:src="@drawable/ic_sports_footbal"
            app:border_width="1dp"
            app:civ_border_width="1dp"
            app:layout_constraintStart_toEndOf="@ id/txtEventName"
            app:layout_constraintTop_toBottomOf="@ id/txtPlayerName"
            app:selector_stroke_color="@color/white" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <ImageView
        android:id="@ id/imgEventImage2"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_online"
        app:border_width="1dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:selector_stroke_color="@color/white" />

    <View
        android:id="@ id/viewLineUpper"
        android:layout_width="1dp"
        android:layout_height="20dp"
        android:background="#41415A"
        app:layout_constraintBottom_toTopOf="@ id/imgEventImage2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@ id/viewLineLower"
        android:layout_width="1dp"
        android:layout_height="20dp"
        android:background="#41415A"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@ id/imgEventImage2" />

    <TextView
        android:id="@ id/txtPlayerName2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_marginTop="15dp"
        android:gravity="center_horizontal"
        android:text="33''"
        android:textColor="#66666a"
        android:textSize="8sp"
        app:layout_constraintEnd_toStartOf="@ id/imgEventImage2"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

here is my layout_item_time_line_right.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@ id/constraintLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:background="@drawable/rounded_corner_time_line_item_bg"
        android:padding="10dp"
        app:layout_constraintStart_toEndOf="@ id/txtPlayerName2"
        app:layout_constraintTop_toTopOf="parent">

        <com.mikhaellopez.circularimageview.CircularImageView
            android:id="@ id/imgPlayerImage"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:src="@drawable/img_upload_profile"
            app:border_color="@color/white"
            app:civ_border_width="1dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:selector_stroke_color="@color/white" />

        <TextView
            android:id="@ id/txtPlayerName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_marginStart="5dp"
            android:gravity="center_horizontal"
            android:text="Neymar"
            android:textColor="#66666a"
            android:textSize="12sp"
            app:layout_constraintStart_toEndOf="@ id/imgPlayerImage"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@ id/txtEventName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_marginStart="5dp"
            android:gravity="center_horizontal"
            android:text="Goal"
            android:textColor="@color/txt_color_live_score"
            android:textSize="12sp"
            app:layout_constraintStart_toEndOf="@ id/imgPlayerImage"
            app:layout_constraintTop_toBottomOf="@ id/txtPlayerName" />

        <com.mikhaellopez.circularimageview.CircularImageView
            android:id="@ id/imgEventImage"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:layout_marginStart="4dp"
            android:layout_marginTop="2dp"
            android:src="@drawable/ic_sports_footbal"
            app:civ_border_width="1dp"
            app:layout_constraintStart_toEndOf="@ id/txtEventName"
            app:layout_constraintTop_toBottomOf="@ id/txtPlayerName"
            app:selector_stroke_color="@color/white" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <ImageView
        android:id="@ id/imgEventImage2"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_online"
        app:border_width="1dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:selector_stroke_color="@color/white" />

    <View
        android:id="@ id/viewLineUpper"
        android:layout_width="1dp"
        android:layout_height="20dp"
        android:background="#41415A"
        app:layout_constraintBottom_toTopOf="@ id/imgEventImage2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@ id/viewLineLower"
        android:layout_width="1dp"
        android:layout_height="20dp"
        android:background="#41415A"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@ id/imgEventImage2" />

    <TextView
        android:id="@ id/txtPlayerName2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_marginTop="15dp"
        android:gravity="center_horizontal"
        android:text="33''"
        android:textColor="#66666a"
        android:textSize="8sp"
        app:layout_constraintStart_toEndOf="@ id/imgEventImage2"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

here is my fragment fragment_time_line.xml

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

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#020321"
    tools:context=".livescore.TimeLineFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@ id/constraintLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:background="@drawable/rounded_border_live_score_tab_table"
            android:padding="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@ id/txtBallPossession"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:gravity="center_horizontal"
                android:text="Ball possession"
                android:textColor="#66666a"
                android:textSize="12sp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <LinearLayout
                android:id="@ id/layout_possession_percentage"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:orientation="horizontal"
                app:layout_constraintTop_toBottomOf="@ id/txtBallPossession"
                tools:layout_editor_absoluteX="0dp">

                <TextView
                    android:id="@ id/txtLeftPercentage"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_horizontal"
                    android:text="70%"
                    android:textColor="#00ffac"
                    android:textSize="12sp"
                    android:textStyle="bold" />

                <ProgressBar
                    android:id="@ id/progressBarLeft"
                    style="?android:attr/progressBarStyleHorizontal"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_weight="1"
                    android:indeterminate="false"
                    android:indeterminateTint="#00ffac"
                    android:max="100"
                    android:progress="50"
                    android:rotation="180" />

                <TextView
                    android:id="@ id/txtRightPercentage"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="30%"
                    android:textColor="#ff0909"
                    android:textSize="12sp"
                    android:textStyle="bold" />

            </LinearLayout>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:background="@drawable/rounded_corner_card"
                android:clipToOutline="true"
                android:scaleType="fitXY"
                android:src="@drawable/img_footbal_ground_green"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@ id/layout_possession_percentage" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@ id/recycler_view_match_timeline"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@ id/constraintLayout" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.core.widget.NestedScrollView>

and here is my JAVA code for fragment

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link TimeLineFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class TimeLineFragment extends Fragment {


    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public TimeLineFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment TimeLineFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static TimeLineFragment newInstance(String param1, String param2) {
        TimeLineFragment fragment = new TimeLineFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    private View mView;
    private RecyclerView recyclerViewMatchTimeline;
    private ArrayList<MatchTimeLine> items = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        mView = inflater.inflate(R.layout.fragment_time_line, container, false);

        recyclerViewMatchTimeline = mView.findViewById(R.id.recycler_view_match_timeline);

        LinearLayoutManager matchTimelineLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        recyclerViewMatchTimeline.setHasFixedSize(true);
        recyclerViewMatchTimeline.setLayoutManager(matchTimelineLayoutManager);

        recyclerViewMatchTimeline.setAdapter(new TimeLineMatchEventsRecyclerViewAdapter(items));

        return mView;

    }
}

and lastly my magic Adapter TimeLineMatchEventsRecyclerViewAdapter.java (copied from stackoverflow answer)

public class TimeLineMatchEventsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<MatchTimeLine> mModelList;


    public TimeLineMatchEventsRecyclerViewAdapter(List<MatchTimeLine> modelList) {
        this.mModelList = modelList;
    }

    @Override
    public int getItemViewType(int position) {
        // Just as an example, return 0 or 2 depending on position
        // Note that unlike in ListView adapters, types don't have to be contiguous
        return position % 2 * 2;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        switch (viewType) {
            case 0:

                LayoutItemTimeLineLeftBinding bindingLeftView = LayoutItemTimeLineLeftBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
                return new ViewHolderLeft(bindingLeftView);

            case 2:
                LayoutItemTimeLineRightBinding bindingRightView = LayoutItemTimeLineRightBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
                return new ViewHolderRight(bindingRightView);

            default:
                LayoutItemTimeLineRightBinding bindingRightDefault = LayoutItemTimeLineRightBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
                return new ViewHolderRight(bindingRightDefault);
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") int position) {
        // final Team team = mModelList.get(position);

        switch (holder.getItemViewType()) {
            case 0:
                ViewHolderLeft viewHolderLeft = (ViewHolderLeft) holder;
                break;

            case 2:
                ViewHolderRight viewHolderRight = (ViewHolderRight) holder;
                break;

        }

    }

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

    class ViewHolderLeft extends RecyclerView.ViewHolder {

        LayoutItemTimeLineLeftBinding binding;

        public ViewHolderLeft(LayoutItemTimeLineLeftBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }

    class ViewHolderRight extends RecyclerView.ViewHolder {

        LayoutItemTimeLineRightBinding binding;

        public ViewHolderRight(LayoutItemTimeLineRightBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }
}

Here is the output I got

enter image description here

  • Related