簡體   English   中英

使用導航組件單擊 RecyclerView 項目時如何從 RecyclerView OnClick 偵聽器更改片段

[英]How to change fragment from the Recycler View OnClick Listener when RecyclerView item is clicked using Navigation Components

基本上我想在 recyclerView 列表中單擊一個項目時更改片段。 但是當我在RecyclerViewAdapterForClassListOnClick方法中執行此操作時,它顯示錯誤

NavHostFragment.findNavController(SecondFragment.this).navigate(R.id.action_SecondFragment_to_studentListFragment);

MainActivity.java


import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.android.studentattendancerecorder.databinding.ActivityMainBinding;

import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration appBarConfiguration;
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.toolbar);

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.about) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.StudentAttendanceRecorder.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/Theme.StudentAttendanceRecorder.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

第一片段.java


import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.RecyclerView;

import com.android.studentattendancerecorder.Adapters.RecyclerViewAdapterForClassList;
import com.android.studentattendancerecorder.databinding.FragmentFirstBinding;

public class FirstFragment extends Fragment {

    private FragmentFirstBinding binding;

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {

        binding = FragmentFirstBinding.inflate(inflater, container, false);
        return binding.getRoot();

    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        binding.buttonFirst.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavHostFragment.findNavController(FirstFragment.this)
                        .navigate(R.id.action_FirstFragment_to_SecondFragment);
            }
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

}

fragment_first.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="match_parent"
    tools:context=".FirstFragment">

    <TextView
        android:id="@+id/textview_first"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_first_fragment"
        app:layout_constraintBottom_toTopOf="@id/button_first"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_first"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/next"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textview_first" />
</androidx.constraintlayout.widget.ConstraintLayout>

SecondFragment.java


import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.studentattendancerecorder.Adapters.RecyclerViewAdapterForClassList;
import com.android.studentattendancerecorder.Model.ClassAndSubjectDetails;
import com.android.studentattendancerecorder.databinding.FragmentSecondBinding;

import java.util.ArrayList;

public class SecondFragment extends Fragment {

    private RecyclerView recyclerViewClass;
    private RecyclerViewAdapterForClassList recyclerViewAdapterForClassList;
private ArrayList<ClassAndSubjectDetails> classAndSubjectDetailsArrayList;
private ArrayAdapter<String> arrayAdapter;
    private FragmentSecondBinding binding;

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {

        binding = FragmentSecondBinding.inflate(inflater, container, false);
        return binding.getRoot();

    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        recyclerViewClass= view.findViewById(R.id.recyclerViewClass);
        recyclerViewClass.setHasFixedSize(true);
        recyclerViewClass.setLayoutManager(new LinearLayoutManager(getActivity()));
classAndSubjectDetailsArrayList=new ArrayList<ClassAndSubjectDetails>();
classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA I","Operating System"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA II","Oops"));
        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA II","Oops"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("M.Tech","System Design"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("B.tech.","Computer Network"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA","Teleport System"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA II","Operating System"));
        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA II","Oops"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("M.Tech","System Design"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("B.tech.","Computer Network"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA","Teleport System"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA II","Operating System"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("M.Tech","System Design"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("B.tech.","Computer Network"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA","Teleport System"));

        classAndSubjectDetailsArrayList.add(new ClassAndSubjectDetails("MCA II","Operating System"));



        recyclerViewAdapterForClassList=new RecyclerViewAdapterForClassList(getContext(),classAndSubjectDetailsArrayList);
        recyclerViewClass.setAdapter(recyclerViewAdapterForClassList);


      /*  binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavHostFragment.findNavController(SecondFragment.this)
                        .navigate(R.id.action_SecondFragment_to_FirstFragment);
            }
        });*/
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

}

fragment_second.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="match_parent"
    tools:context=".SecondFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewClass"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="36dp"
        android:layout_marginBottom="36dp"
        android:clickable="true"
        android:src="@android:drawable/ic_input_add"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

StudentListFragment.java


import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


public class StudentListFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_student_list, container, false);
    }
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

    }


}

RecyclerViewAdpaterForClassList.java


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.RecyclerView;

import com.android.studentattendancerecorder.FirstFragment;
import com.android.studentattendancerecorder.Model.ClassAndSubjectDetails;
import com.android.studentattendancerecorder.R;
import com.android.studentattendancerecorder.SecondFragment;
import com.google.android.material.snackbar.Snackbar;

import java.util.List;

public class RecyclerViewAdapterForClassList extends RecyclerView.Adapter<RecyclerViewAdapterForClassList.ViewHolder> {
    private Context context;
    private List<ClassAndSubjectDetails> classAndSubjectDetailsList;

    public RecyclerViewAdapterForClassList(Context context, List<ClassAndSubjectDetails> classAndSubjectDetailsList) {
        this.context = context;
        this.classAndSubjectDetailsList = classAndSubjectDetailsList;
    }
//create card/item/holder
    @NonNull
    @Override
    public RecyclerViewAdapterForClassList.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.classlistitem,parent,false);
        return new ViewHolder(view);
    }

    //set details of each holder/card/item
    @Override
    public void onBindViewHolder(@NonNull RecyclerViewAdapterForClassList.ViewHolder holder, int position) {
        ClassAndSubjectDetails classAndSubjectDetails=classAndSubjectDetailsList.get(position);
holder.class_name.setText(classAndSubjectDetails.getClass_name());
        holder.subject_name.setText(classAndSubjectDetails.getSubject_name());

    }

    @Override
    public int getItemCount() {
        return classAndSubjectDetailsList.size();
    }
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView class_name;
        public TextView subject_name;        
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            class_name=itemView.findViewById(R.id.className);

            subject_name=itemView.findViewById(R.id.subjectName);
        }

        @Override
        public void onClick(View v) {
        }
    }
}

fragment_student_list.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StudentListFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

ClassAndSubjectDetails.java


import androidx.annotation.NonNull;

public class ClassAndSubjectDetails {
    private String class_name;
    private String subject_name;
    static int id=0;

    public ClassAndSubjectDetails(String aClass, String subject) {
        class_name = aClass;
        subject_name = subject;
    }

    public String getClass_name() {
        return class_name;
    }

    public void setClass_name(String class_name) {
        this.class_name = class_name;
    }

    public String getSubject_name() {
        return subject_name;
    }

    public void setSubject_name(String subject_name) {
        this.subject_name = subject_name;
    }

    public static int getId() {
        return id;
    }

    public static void setId(int id) {
        ClassAndSubjectDetails.id = id;
    }
}

類列表項.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="100dp">

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

        <TextView
            android:id="@+id/className"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="12dp"
            android:layout_marginTop="12dp"
            android:text="MCA ( IIIrd Sem. )"
            android:textAllCaps="true"
            android:textColor="#000000"
            android:textSize="34sp"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/subjectName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="12dp"
            android:layout_marginTop="3dp"
            android:text="Object Oriented Programming"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/className" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

導航圖.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_graph"
    app:startDestination="@id/FirstFragment">

    <fragment
        android:id="@+id/FirstFragment"
        android:name="com.android.studentattendancerecorder.FirstFragment"
        android:label="@string/first_fragment_label"
        tools:layout="@layout/fragment_first">

        <action
            android:id="@+id/action_FirstFragment_to_SecondFragment"
            app:destination="@id/SecondFragment" />
    </fragment>
    <fragment
        android:id="@+id/SecondFragment"
        android:name="com.android.studentattendancerecorder.SecondFragment"
        android:label="@string/second_fragment_label"
        tools:layout="@layout/fragment_second">

        <action
            android:id="@+id/action_SecondFragment_to_FirstFragment"
            app:destination="@id/FirstFragment" />
        <action
            android:id="@+id/action_SecondFragment_to_studentListFragment"
            app:destination="@id/studentListFragment" />
    </fragment>
    <fragment
        android:id="@+id/studentListFragment"
        android:name="com.android.studentattendancerecorder.StudentListFragment"
        android:label="fragment_student_list"
        tools:layout="@layout/fragment_student_list" >
        <action
            android:id="@+id/action_studentListFragment_to_SecondFragment"
            app:destination="@id/SecondFragment" />
    </fragment>
</navigation>

也許它可以解決你的問題。

在 viewModel 中添加接口

public interface CallListener{

    public void myChoice(int position);

}

在您的 Fragment 中創建實現,並在構造函數中提供您的 viewModel

public RecyclerViewAdapterForClassList(Context context, 
List<ClassAndSubjectDetails> classAndSubjectDetailsList, CallListener listener) {
    this.context = context;
    this.classAndSubjectDetailsList = classAndSubjectDetailsList;
    this.listener = listener;
}

然后將偵聽器添加到您的持有人

holder.itemView.setOnClickListener((view) ->{
        if (listener!= null) listener.myChoice(holder.getAdapterPosition());
});

或者你可以這樣稱呼

    AppCompatActivity activity = ((AppCompatActivity) holder.itemView.getContext());
    Navigation.findNavController(activity,R.id.nav_host_fragment_content_main).navigate(R.id.myFragment);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM