从适配器 RecyclerView 打开片段

Posted

技术标签:

【中文标题】从适配器 RecyclerView 打开片段【英文标题】:Open fragment from adapter RecyclerView 【发布时间】:2017-12-20 17:30:40 【问题描述】:

我的应用遇到了一些问题。我有带有 CardView 的 recyclerView。我想打开带有信息描述的新片段......但这没关系。

这是我的适配器

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.DataViewHolder>

//here
private OnRecyclerViewItemClickListener mClickListener;

public static class DataViewHolder extends RecyclerView.ViewHolder
    CardView cardView;
    TextView textViewName;
    TextView textViewRegion;

    public DataViewHolder(View itemView) 
        super(itemView);
        cardView = (CardView) itemView.findViewById(R.id.cardView);
        textViewName = (TextView) itemView.findViewById(R.id.textViewName);
        textViewRegion = (TextView) itemView.findViewById(R.id.textViewRegion);
    


private List<DataJSON> dataList;

RVAdapter(List<DataJSON> dataList)
    this.dataList = dataList;


@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) 
    super.onAttachedToRecyclerView(recyclerView);


@Override
public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
    DataViewHolder dvh = new DataViewHolder(v);
    return dvh;


private DataJSON getItem(int position)
    return dataList.get(position);


@Override
public void onBindViewHolder(DataViewHolder holder, final int position) 
    holder.textViewName.setText(dataList.get(position).getPierName());
    holder.textViewRegion.setText(dataList.get(position).getRegion());

    holder.cardView.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            Log.d("myLog", "Click-clack position " + position);
            if (mClickListener != null)
                Log.d("myLog", "mClickListener != null");
                mClickListener.onClick(position);
             else Log.d("myLog", "mClickListener = null");
        
    );


//here
public interface OnRecyclerViewItemClickListener 
    void onClick(int parameter);


@Override
public int getItemCount() 
    return dataList.size();

在 onBindViewHolder 我有 onClick 我在 MainActivity 中调用 OnRecyclerViewItemClickListener onClick。

这是 MainActivity。

public class MainActivity extends AppCompatActivity implements RVAdapter.OnRecyclerViewItemClickListener
private CardViewFragment cardViewFragment;
private DetailFragment detailFragment;

private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d("MyTag", "onCreate");

    //Create FragmentManager
    fragmentManager = getSupportFragmentManager();

    //Initialization fragments
    cardViewFragment = new CardViewFragment();
    detailFragment = new DetailFragment();


    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container, cardViewFragment, CardViewFragment.TAG);
    fragmentTransaction.commit();


@Override
public void onClick(int parameter) 
    Log.d("myLog", "Hi, from MainActivity");
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container, detailFragment, DetailFragment.TAG);
    fragmentTransaction.commit();

我有一个错误,mClickListener 是空对象,并且理解它, 但我真的不知道,如何解决它。

这是 CardViewFragment

public class CardViewFragment extends Fragment implements RVAdapter.OnRecyclerViewItemClickListener 

public static final String TAG = "CardViewFragment";

private List<DataJSON> dataJSONList;
private RecyclerView recyclerView;
RVAdapter rvAdapter;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    View rootView = inflater.inflate(R.layout.activity_card_view_fragment, container, false);

    dataJSONList = new ArrayList<>();
    recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setHasFixedSize(true);

    loadDataFromServer();
    //testData();

    rvAdapter = new RVAdapter(this, dataJSONList);
    recyclerView.setAdapter(rvAdapter);

    getActivity();
    return rootView;


private void testData()
    //dataJSONList.add(new DataJSON(0, "RiverIsland", "Moscow", "Moscow is the capital of Russia"));
    //dataJSONList.add(new DataJSON(1, "kek", "Lol", "Scream"));
    DataJSON data2 = new DataJSON(0, "RiverIsland", "Moscow", "Moscow is the capital of Russia");
    dataJSONList.add(data2);


String strJson;
private void loadDataFromServer()  

    AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>()
        @Override
        protected String doInBackground(Void... voids) 
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url("https://gesmetrics.ru/testpiers.php").build();
            Response response;

            try 
                response = client.newCall(request).execute();
                strJson = response.body().string();
             catch (IOException e) 
                e.printStackTrace();
            

            return strJson;
        

        @Override
        protected void onPostExecute(String strJson) 
            super.onPostExecute(strJson);
            Log.d("myLog", strJson);

            //DataJSON data2 = new DataJSON(0, "RiverIsland", "Moscow", "Moscow is the capital of Russia");
            //dataJSONList.add(data2);

            try 
                JSONArray jsonArray = new JSONArray(strJson);
                for (int i = 0; i < jsonArray.length(); i++) 
                    JSONObject object = jsonArray.getJSONObject(i);

                    int id = object.getInt("pierId");
                    String name = object.getString("pierName");
                    String region = object.getString("region");
                    String description = object.getString("description");
                    DataJSON data = new DataJSON(i, name, region, description);
                    //nothing happens here
                    dataJSONList.add(data);
                
             catch (JSONException e) 
                System.out.println("Issue");
            
            rvAdapter.notifyDataSetChanged();
        

    ;
    task.execute();


@Override
public void onClick(int parameter) 


主活动

public class MainActivity extends AppCompatActivity implements RVAdapter.OnRecyclerViewItemClickListener
private CardViewFragment cardViewFragment;
private DetailFragment detailFragment;

private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d("MyTag", "onCreate");

    //Create FragmentManager
    fragmentManager = getSupportFragmentManager();

    //Initialization fragments
    cardViewFragment = new CardViewFragment();
    detailFragment = new DetailFragment();


    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container, cardViewFragment, CardViewFragment.TAG);
    fragmentTransaction.commit();


@Override
public void onClick(int parameter) 
    Log.d("myLog", "Hi, from MainActivity");
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container, detailFragment, DetailFragment.TAG);
    fragmentTransaction.commit();

非常感谢!

【问题讨论】:

你在哪里给mClickListener赋值? 【参考方案1】:

    通过适配器的构造函数传递点击监听器。

    RVAdapter(OnRecyclerViewItemClickListener listener,List<DataJSON> dataList)
        mClickListener = listener;
        this.dataList = dataList;
    
    

    CardViewFragment 类中进行片段事务

    public class CardViewFragment extends Fragment implements RVAdapter.OnRecyclerViewItemClickListener 
    
    @Override
    public void onClick(int parameter) 
        //either add fragment
        //getChildFragmentManager().beginTransaction()
        //        .add(new DetailFragment(), null)
        //        .commit();
        //or if you defined any container for DetailFragment(like frame layout) in your fragment layout file which is activity_card_view_fragment.xml just use replace
        getChildFragmentManager().beginTransaction()
                .replace(R.id.container, new DetailFragment())
                .commit();
    
        
    
    

【讨论】:

但是,我必须在 RecyclerView 的第一个片段中添加 (rvAdapter = new RVAdapter(dataJSONList);) 什么? 不,您需要在您的片段或您设置适配器的任何地方实现OnRecyclerViewItemClickListener 并在适配器创建时传递它。试试这个new RvAdapter(this, dataJSONList); new RvAdapter(this, dataJSONList); 在我的第一个片段中使用 recyclerView 不起作用“错误:(43, 26) 错误:不兼容的类型:CardViewFragment 无法转换为 OnRecyclerViewItemClickListener” 先实现监听接口。像这样更改您的片段CardViewFragment implements OnRecyclerViewItemClickListener 请查看我的问题,我已经添加了我的 CardViewFragment。空的 OnClick 可能有一些问题?因为它仍然不起作用对不起我

以上是关于从适配器 RecyclerView 打开片段的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数

从 recyclerview 的适配器访问父片段方法

需要解释从适配器发送数据到片段

将对象列表从片段传递到 recyclerView 适配器

从RecyclerView适配器更新活动或片段的视图

如何在 Recyclerview Item Click 上打开新片段?