在运行时将数据添加到片段中的片段中的RecyclerView中,在单独的片段中创建数据

时间:2019-03-09 18:17:18

标签: java android android-fragments

我创建了一个包含3个不同片段的应用程序。一个片段有一个按钮,可将数据添加到一个单独的片段中的recyclerview中,但是它无法正常运行。我曾尝试使用FragmentManager导致空指针异常,我曾尝试在我的适配器和数据类中使用notifyDataChanged,它们不会更新片段中的数据,并且我尝试重置了也会导致空指针异常的viewholder。我的想法不多了。

我的适配器在这里:

package com.example.dogwalk;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;

import java.util.ArrayList;

public class DogInfoAdapter extends RecyclerView.Adapter<DogInfoAdapter.ViewHolder>
{
    private static final String TAG = "DogInfoAdapter";

    private ArrayList<String> mDogType;
    private ArrayList<String> mImages;
    private ArrayList<String> mDogInfo;
    private Context mContext;

    public DogInfoAdapter(ArrayList<String> mDogType, ArrayList<String> mImages,
                          ArrayList<String> mDogInfo, Context mContext)
    {
        this.mDogType = mDogType;
        this.mImages = mImages;
        this.mDogInfo = mDogInfo;
        this.mContext = mContext;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i)
    {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_listitem_doginfo, parent, false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position)
    {
        Log.d(TAG, "onBindViewHolder: called.");

        Glide.with(mContext)
                .asBitmap()
                .load(mImages.get(position))
                .into(holder.imageView);

        holder.dogType.setText(mDogType.get(position));

        holder.dogInfo.setText(mDogInfo.get(position));
    }

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


    public class ViewHolder extends RecyclerView.ViewHolder
    {

        ImageView imageView;
        TextView dogType;
        TextView dogInfo;
        RelativeLayout parentLayout;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.image);
            dogType = itemView.findViewById(R.id.dogType);
            dogInfo = itemView.findViewById(R.id.dogInfo);
            parentLayout = itemView.findViewById(R.id.parent_layout);

        }
    }

}

还有我的数据类

请注意,我在底部的“ AddData”方法只是为了测试不同的解决方案,计划是在单独的片段中动态添加数据。

package com.example.dogwalk;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;


public class DogInfo extends Fragment 
{
    private static final String TAG = "DogInfo";
    private ArrayList<String> mNames = new ArrayList<>();
    private  ArrayList<String> mImageUrls = new ArrayList<>();
    private ArrayList<String> mDogInfo = new ArrayList<>();
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private View mView;

    public static DogInfo newInstance() {
        DogInfo fragment = new DogInfo();
        return fragment;
    }


    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        initImageBitmaps();
        View mView = inflater.inflate(R.layout.doginfo_layout, container, false);
        mRecyclerView = mView.findViewById(R.id.recyclerview);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL));
        mAdapter = new DogInfoAdapter(mNames, mImageUrls, mDogInfo, mView.getContext());
        mLayoutManager = new LinearLayoutManager(getContext());
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);

        return mView;
    }

    private void initImageBitmaps()
    {
        Log.d(TAG, "initImageBitmaps: Preparing Bitmaps.");

        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/d/de/Smooth_Dachshund_red_and_tan_portrait.jpg");
        mNames.add("Dachshund");
        mDogInfo.add("You should be giving your dog a 45-60 minute walk a day (maybe split in two lots). Once adult, your Dachshund will take any amount of exercise you care to give. ");


        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/2/26/YellowLabradorLooking_new.jpg");
        mNames.add("Labrador");
        mDogInfo.add("A normal, healthy adult Labrador Retriever will need 1 hour of exercise every day. The more relaxed Labs just 45 minutes per day, the more energetic 1.5 hours+.");

        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/2/2c/West_Highland_White_Terrier_Krakow.jpg");
        mNames.add("West Highland Terrier");
        mDogInfo.add("The length of the walk is only limited by your time and energy as a West Highland Terrier can go all day long. Ideally, the minimum should be 30 to 60 minutes daily. This can be just once a day, but ideally split over two walks a day");

        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/f/fa/Buster_the_red_grizzle_border_terrier_%282006%29.jpg");
        mNames.add("Border Terrier");
        mDogInfo.add("The length of the walk is only limited by your time and energy as a Border Terrier can go all day long. Ideally, the minimum should be 45 to 60 minutes daily. This can be just once a day, but two walks a day would be better.");


        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/6/6d/Alaskan_malamut_465.jpg");
        mNames.add("Alaskan Malamut");
        mDogInfo.add("A couple of daily walks (one is at least 45 minutes) or a shorter walk and a vigorous play session (30 minutes or more). Malamutes can be stubborn, but they are also eager to please. Training early on will make play and exercise and life in general easier.");


        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/6/6c/Border_Collie_rojo_mirlo_tricolor_%28Birdy_de_los_Baganicos%29.jpg");
        mNames.add("Border Collie");
        mDogInfo.add("Although as much as they possibly can should be the right answer, but at least 20-30 minutes of running everyday is ideal. However, undoubtedly your Border Collie would definitely prefer a lot more.");


//        mImageUrls.add("https://en.wikipedia.org/wiki/English_Springer_Spaniel#/media/File:%C3%89pagneul_Anglais.jpg");
//        mNames.add("Springer Spaniel");

        mImageUrls.add("https://upload.wikimedia.org/wikipedia/commons/d/de/Beagle_Upsy.jpg");
        mNames.add("Beagle");
        mDogInfo.add("You should walk your Beagle for a minimum of 20 minutes, ideally 30, and some Beagles may need up to 40 minutes.");

//
//        mImageUrls.add("https://en.wikipedia.org/wiki/Shiba_Inu#/media/File:Shiba_inu_taiki.jpg");
//        mNames.add("Shiba Inu");
//
//        mImageUrls.add("https://en.wikipedia.org/wiki/Samoyed_dog#/media/File:Samojed00.jpg");
//        mNames.add("Samoyed");
    }

    public void AddData()
    {

        mNames.add("Test");
        mImageUrls.add("Test");
        mDogInfo.add("Test");
        FragmentManager manager = getActivity().getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        Fragment newFragment = this;
        this.onDestroy();
        ft.remove(this);
        ft.replace(getView().getId(),newFragment);
        //container is the ViewGroup of current fragment
        ft.addToBackStack(null);
        ft.commit();
    }



}

1 个答案:

答案 0 :(得分:0)

您有一个包含两个片段的活动:

  • 持有recyclerView的FragmentB
  • FragmentA,可将项目动态添加到FragmentB的recyclerView中

因此,需要的是FragmentA必须具有对FragmentB的引用才能对其进行修改。 (如果我错了,请纠正我)

有几种方法可以实现这一点:

一种方法是让片段通过它们的活动相互交谈,如下所示:

  1. 每当活动要在recyclerView中修改项目时,它都要收听FragmentA;这可以通过创建@@ FragmentA接口来完成,该接口由活动实现
  2. 当活动由FragmentA触发时,它必须将请求发送到 FragmentB的public方法以修改recyclerView

有关代码段,您可以参考我的回答here;区别在于FragmentA会更改TextView而不是RecyclerView的内容...如果您需要RecyclerView的另一个代码段,请告诉我。