Как сохранить состояние viewpager и recyclerview во фрагменте? - PullRequest
0 голосов
/ 12 июля 2020

Прошло всего несколько дней с тех пор, как я начал изучать Android, и сегодня был день, когда я наткнулся на «фрагменты». Создавать фрагменты было легко, но я не мог сохранить состояние, когда переключаю вкладки в нижнем меню навигации. Мое приложение простое, оно использует viewpager2 и recyclerview для просмотра некоторых видео. Вот код:

Фрагмент:

package com.example.application;

import android.animation.ValueAnimator;
import android.graphics.Color;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.VideoView;

import org.w3c.dom.Text;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link firstFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class firstFragment 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 firstFragment() {
        // 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 firstFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static firstFragment newInstance(String param1, String param2) {
        firstFragment fragment = new firstFragment();
        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);
        }

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        
        // Inflate the layout for this fragment
        View root =  inflater.inflate(R.layout.fragment_first, container, false);
        final ViewPager2 videosViewPager = root.findViewById(R.id.videosViewPager);

            List<VideoItem> videoItems = new ArrayList<>();


            VideoItem videoItem1 = new VideoItem();
            videoItem1.videoURL = "https://infinityandroid.com/videos/video1.mp4";
            videoItem1.videoTitle = "Title";
            videoItem1.videoDescription = "Description";
            videoItems.add(videoIem1);

            VideoItem videoItem2 = new VideoItem();
            videoItem2.videoURL = "https://infinityandroid.com/videos/video2.mp4";
            videoItem2.videoTitle = "Title";
            videoItem2.videoDescription = "Description";
            videoItems.add(videoItem2);

            VideoItem videoItem3 = new VideoItem();
            videoItem3.videoURL = "https://infinityandroid.com/videos/video3.mp4";
            videoItem3.videoTitle = "Title";
            videoItem3.videoDescription = "Description";
            videoItems.add(videoItem3);

            VideoItem videoItem4 = new VideoItem();
            videoItem4.videoURL = "https://infinityandroid.com/videos/video4.mp4";
            videoItem4.videoTitle = "Title";
            videoItem4.videoDescription = "Description";
            videoItems.add(videoItem4);

            VideoItem videoItem5 = new VideoItem();
            videoItem5.videoURL = "https://infinityandroid.com/videos/video5.mp4";
            videoItem5.videoTitle = "Title";
            videoItem5.videoDescription = "Description";
            videoItems.add(videoItem5);


            videosViewPager.setAdapter(new VideosAdapter(videoItems));


        return root;

    }
}

VideoItem. java:

package com.example.application;

public class VideoItem {
    public String videoURL, videoTitle, videoDescription;
}


VideosAdapter. java:

package com.example.application;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.VideoView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.w3c.dom.Text;

import java.util.List;



public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.VideoViewHolder> {


    private List<VideoItem> videoItems;

    public VideosAdapter(List<VideoItem> videoItems) {
        this.videoItems = videoItems;
    }

    @NonNull
    @Override
    public VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new VideoViewHolder(
               LayoutInflater.from(parent.getContext()).inflate(
                       R.layout.item_container_video,
                       parent,
                       false
               )
        );
    }



    @Override
    public void onBindViewHolder(@NonNull VideoViewHolder holder, int position) {
      holder.setVideoData(videoItems.get(position));
    }

    

    @Override
    public int getItemCount() {
        return videoItems.size();
    }


    static class VideoViewHolder extends RecyclerView.ViewHolder {

        VideoView videoView;
        TextView textVideoTitle, textVideoDescription;
        ProgressBar videoProgressBar;

        public VideoViewHolder(@NonNull View itemView) {
            super(itemView);
            videoView = itemView.findViewById(R.id.videoView);
            textVideoTitle = itemView.findViewById(R.id.textVideoTitle);
            textVideoDescription = itemView.findViewById(R.id.textVideoDescription);
            videoProgressBar = itemView.findViewById(R.id.videoProgressBar);
        }

        void setVideoData(VideoItem videoItem) {
            textVideoTitle.setText(videoItem.videoTitle);
            textVideoDescription.setText(videoItem.videoDescription);
            videoView.setVideoPath(videoItem.videoURL);
            videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    videoProgressBar.setVisibility(View.GONE);
                    mediaPlayer.start();
                    float videoRatio = mediaPlayer.getVideoWidth() / (float) mediaPlayer.getVideoHeight();
                    float screenRatio = videoView.getWidth() / (float) videoView.getHeight();
                    float scale = videoRatio / screenRatio;
                    if(scale >= 1f) {
                        videoView.setScaleX(scale);
                    } else {
                        videoView.setScaleY(1f / scale);
                    }
                }
            });
            videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    mediaPlayer.start();
                }
            });
        }
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что когда я переключаю вкладки из нижнего меню и возвращаюсь к этому фрагменту, первое видео загружается с самого начала и он забывает мою позицию прокрутки. Это плохо, потому что если в будущем, если мне нужно будет добавить больше видео, а фрагмент забудет позицию и просматриваемое в данный момент видео при переключении вкладок, это может быть плохим пользовательским интерфейсом. Я искал ответы на stackoverflow, но не могу понять ни одного из них. Надеюсь, вы сможете найти решение.

Также я хотел бы знать, как большие приложения, такие как instagram и facebook, сохраняют состояние, даже если пользователи просматривают тысячи сообщений, и как они на самом деле реализуют эти методы. Надеюсь, ты ответишь. С уважением

...