无法通过单击图像替换片段
Cannot replace fragment from a click on image
我有一个 navigationDrawer 和一个 Cardview 的 RecyclerView。我希望如果我点击 Cardview 上的图片,我的 Fragment 会发生变化,但什么也没有发生
这是代码:
CardAdapter.java
public class CardAdapter extends FirebaseRecyclerAdapter<Spesa, CardAdapter.cardViewholder> {
// Constructor
public CardAdapter(
FragmentActivity activity, @NonNull FirebaseRecyclerOptions<Spesa> options){
super(options);
}
@Override
protected void
onBindViewHolder(@NonNull cardViewholder holder,
int position, @NonNull Spesa model)
{
holder.amount.setText(model.getDesc());
holder.who.setText(String.valueOf(model.getCosto()));
holder.Description.setText(model.getCategoria());
holder.modifica.setImageResource(R.drawable.edit);
String str = model.getchi();
if(model.getchi().equals("Francesco")){
holder.chiSpende.setImageResource(R.drawable.fra);
}
else if(model.getchi().equals("Angela")){
holder.chiSpende.setImageResource(R.drawable.angela);
}
holder.modifica.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AppCompatActivity activity = (AppCompatActivity) v.getContext();
Fragment myFragment = new InserisciSpesaFragment();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.nav_resoconto, myFragment).addToBackStack(null).commit();
}
}
@NonNull
@Override
public cardViewholder
onCreateViewHolder(@NonNull ViewGroup parent,
int viewType)
{
View view
= LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_layout, parent, false);
return new CardAdapter.cardViewholder(view);
}
class cardViewholder extends RecyclerView.ViewHolder {
CardView cw;
TextView amount, who, Description;
ImageView chiSpende, cancella, modifica;
public cardViewholder(@NonNull View itemView)
{
super(itemView);
amount = itemView.findViewById(R.id.idAmount);
who = itemView.findViewById(R.id.idChiSpende);
Description = itemView.findViewById(R.id.idDescrizioneSpesa);
chiSpende = itemView.findViewById(R.id.ImgSpese);
cancella = itemView.findViewById(R.id.bin);
modifica = itemView.findViewById(R.id.edit);
cw = itemView.findViewById(R.id.myCardView);
});
modifica.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AppCompatActivity activity = (AppCompatActivity) v.getContext();
Fragment frag = new InserisciSpesaFragment();
activity.getSupportFragmentManager().beginTransaction()
.replace(R.id.nav_resoconto, frag).commit();
}
});
}
}
}
这是我要跳的class:InserisciSpesaFragment.java
public class InserisciSpesaFragment extends Fragment {
private Firebase mref;
FirebaseDatabase database = FirebaseDatabase.getInstance();
private InserisciSpesa inserisciSpesa;
private FragmentInserisciBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
inserisciSpesa =
new ViewModelProvider(this).get(InserisciSpesa.class);
binding = FragmentInserisciBinding.inflate(inflater, container, false);
View root = binding.getRoot();
Button btn = (Button) binding.BtnInsert;
EditText txtcosto = (EditText) binding.EdittextCosto;
EditText txtdesc = (EditText) binding.EdittextSpesa;
Spinner spinCat = (Spinner) binding.spinnerCategorie;
Spinner spinChi = (Spinner) binding.spinnerChi;
DatePicker datePicker = (DatePicker) binding.DatePicker;
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
String my = (String) snapshot.getValue();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
};
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!CampiVuoti(txtdesc.getText().toString(), txtcosto.getText().toString())){
Snackbar.make(view, "Attenzione, sono presenti campi vuoti!", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
else {
Spesa spesa = new Spesa(txtdesc.getText().toString(), Double.parseDouble(txtcosto.getText().toString()),
spinCat.getSelectedItem().toString(), spinChi.getSelectedItem().toString(),
datePicker.getDayOfMonth(), datePicker.getMonth() + 1, datePicker.getYear());
addDatatoFirebase(spesa);
Snackbar.make(view, "Spesa inserita correttamente", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
});
inserisciSpesa.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
//textView.setText(s);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
问题出在onclick,尤其是在:
public void onClick(View v) {
Fragment frag = new InserisciSpesaFragment();
FragmentManager fm = frag.getActivity().getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.nav_resoconto, frag)
.commit();
}
这是 mobile_navigation.xml
的 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/mobile_navigation"
app:startDestination="@+id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="com.example.frangela.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/nav_gallery"
android:name="com.example.frangela.ui.gallery.GalleryFragment"
android:label="@string/menu_gallery"
tools:layout="@layout/fragment_gallery" />
<fragment
android:id="@+id/nav_slideshow"
android:name="com.example.frangela.ui.slideshow.InserisciSpesaFragment"
android:label="@string/menu_slideshow"
tools:layout="@layout/fragment_inserisci" />
<fragment
android:id="@+id/nav_stipendio"
android:name="com.example.frangela.ui.stipendio.InserisciStipendioFragment"
android:label="@string/menu_stipendio"
tools:layout="@layout/fragment_stipendio" />
<fragment
android:id="@+id/nav_resoconto"
android:name="com.example.frangela.ui.resocard.ResocardFragment"
android:label="@string/Resoconto"
tools:layout="@layout/fragment_resocard" />
</navigation>
谢谢
您正在创建新片段
Fragment frag = new InserisciSpesaFragment();
然后您正试图从中获取 Activity
FragmentManager fm = frag.getActivity().getSupportFragmentManager();
此片段在 getActivity()
调用时未添加到任何 Activity
,您应该在此处获得 NullPointerException
...(崩溃,超过“没有任何反应")
考虑保留对构造函数
中获得的FragmentManager
的引用
public class CardAdapter extends FirebaseRecyclerAdapter<Spesa, CardAdapter.cardViewholder> {
private FragmentManager fm;
// Constructor
public CardAdapter(FragmentActivity activity, @NonNull FirebaseRecyclerOptions<Spesa> options){
super(options);
fm = activity.getSupportFragmentManager();
}
然后在 onClick
中使用它而不是尝试从 not-added Fragment
中获取它
public void onClick(View v) {
Fragment frag = new InserisciSpesaFragment();
//FragmentManager fm = frag.getActivity().getSupportFragmentManager();
fm.beginTransaction() // use fm obtained in constructor
.replace(R.id.nav_resoconto, frag)
.commit();
}
顺便说一句。我怀疑此代码是否有效,因为 R.id.nav_resoconto
是 XML 中已声明片段的 ID。 replace(...)
method needs reference to fragment container view (in doc named containerViewId
). read doc carefully 用于正确的导航切换
我有一个 navigationDrawer 和一个 Cardview 的 RecyclerView。我希望如果我点击 Cardview 上的图片,我的 Fragment 会发生变化,但什么也没有发生 这是代码:
CardAdapter.java
public class CardAdapter extends FirebaseRecyclerAdapter<Spesa, CardAdapter.cardViewholder> {
// Constructor
public CardAdapter(
FragmentActivity activity, @NonNull FirebaseRecyclerOptions<Spesa> options){
super(options);
}
@Override
protected void
onBindViewHolder(@NonNull cardViewholder holder,
int position, @NonNull Spesa model)
{
holder.amount.setText(model.getDesc());
holder.who.setText(String.valueOf(model.getCosto()));
holder.Description.setText(model.getCategoria());
holder.modifica.setImageResource(R.drawable.edit);
String str = model.getchi();
if(model.getchi().equals("Francesco")){
holder.chiSpende.setImageResource(R.drawable.fra);
}
else if(model.getchi().equals("Angela")){
holder.chiSpende.setImageResource(R.drawable.angela);
}
holder.modifica.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AppCompatActivity activity = (AppCompatActivity) v.getContext();
Fragment myFragment = new InserisciSpesaFragment();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.nav_resoconto, myFragment).addToBackStack(null).commit();
}
}
@NonNull
@Override
public cardViewholder
onCreateViewHolder(@NonNull ViewGroup parent,
int viewType)
{
View view
= LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_layout, parent, false);
return new CardAdapter.cardViewholder(view);
}
class cardViewholder extends RecyclerView.ViewHolder {
CardView cw;
TextView amount, who, Description;
ImageView chiSpende, cancella, modifica;
public cardViewholder(@NonNull View itemView)
{
super(itemView);
amount = itemView.findViewById(R.id.idAmount);
who = itemView.findViewById(R.id.idChiSpende);
Description = itemView.findViewById(R.id.idDescrizioneSpesa);
chiSpende = itemView.findViewById(R.id.ImgSpese);
cancella = itemView.findViewById(R.id.bin);
modifica = itemView.findViewById(R.id.edit);
cw = itemView.findViewById(R.id.myCardView);
});
modifica.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AppCompatActivity activity = (AppCompatActivity) v.getContext();
Fragment frag = new InserisciSpesaFragment();
activity.getSupportFragmentManager().beginTransaction()
.replace(R.id.nav_resoconto, frag).commit();
}
});
}
}
}
这是我要跳的class:InserisciSpesaFragment.java
public class InserisciSpesaFragment extends Fragment {
private Firebase mref;
FirebaseDatabase database = FirebaseDatabase.getInstance();
private InserisciSpesa inserisciSpesa;
private FragmentInserisciBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
inserisciSpesa =
new ViewModelProvider(this).get(InserisciSpesa.class);
binding = FragmentInserisciBinding.inflate(inflater, container, false);
View root = binding.getRoot();
Button btn = (Button) binding.BtnInsert;
EditText txtcosto = (EditText) binding.EdittextCosto;
EditText txtdesc = (EditText) binding.EdittextSpesa;
Spinner spinCat = (Spinner) binding.spinnerCategorie;
Spinner spinChi = (Spinner) binding.spinnerChi;
DatePicker datePicker = (DatePicker) binding.DatePicker;
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
String my = (String) snapshot.getValue();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
};
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!CampiVuoti(txtdesc.getText().toString(), txtcosto.getText().toString())){
Snackbar.make(view, "Attenzione, sono presenti campi vuoti!", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
else {
Spesa spesa = new Spesa(txtdesc.getText().toString(), Double.parseDouble(txtcosto.getText().toString()),
spinCat.getSelectedItem().toString(), spinChi.getSelectedItem().toString(),
datePicker.getDayOfMonth(), datePicker.getMonth() + 1, datePicker.getYear());
addDatatoFirebase(spesa);
Snackbar.make(view, "Spesa inserita correttamente", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
});
inserisciSpesa.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
//textView.setText(s);
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
问题出在onclick,尤其是在:
public void onClick(View v) {
Fragment frag = new InserisciSpesaFragment();
FragmentManager fm = frag.getActivity().getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.nav_resoconto, frag)
.commit();
}
这是 mobile_navigation.xml
的 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/mobile_navigation"
app:startDestination="@+id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="com.example.frangela.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/nav_gallery"
android:name="com.example.frangela.ui.gallery.GalleryFragment"
android:label="@string/menu_gallery"
tools:layout="@layout/fragment_gallery" />
<fragment
android:id="@+id/nav_slideshow"
android:name="com.example.frangela.ui.slideshow.InserisciSpesaFragment"
android:label="@string/menu_slideshow"
tools:layout="@layout/fragment_inserisci" />
<fragment
android:id="@+id/nav_stipendio"
android:name="com.example.frangela.ui.stipendio.InserisciStipendioFragment"
android:label="@string/menu_stipendio"
tools:layout="@layout/fragment_stipendio" />
<fragment
android:id="@+id/nav_resoconto"
android:name="com.example.frangela.ui.resocard.ResocardFragment"
android:label="@string/Resoconto"
tools:layout="@layout/fragment_resocard" />
</navigation>
谢谢
您正在创建新片段
Fragment frag = new InserisciSpesaFragment();
然后您正试图从中获取 Activity
FragmentManager fm = frag.getActivity().getSupportFragmentManager();
此片段在 getActivity()
调用时未添加到任何 Activity
,您应该在此处获得 NullPointerException
...(崩溃,超过“没有任何反应")
考虑保留对构造函数
中获得的FragmentManager
的引用
public class CardAdapter extends FirebaseRecyclerAdapter<Spesa, CardAdapter.cardViewholder> {
private FragmentManager fm;
// Constructor
public CardAdapter(FragmentActivity activity, @NonNull FirebaseRecyclerOptions<Spesa> options){
super(options);
fm = activity.getSupportFragmentManager();
}
然后在 onClick
中使用它而不是尝试从 not-added Fragment
public void onClick(View v) {
Fragment frag = new InserisciSpesaFragment();
//FragmentManager fm = frag.getActivity().getSupportFragmentManager();
fm.beginTransaction() // use fm obtained in constructor
.replace(R.id.nav_resoconto, frag)
.commit();
}
顺便说一句。我怀疑此代码是否有效,因为 R.id.nav_resoconto
是 XML 中已声明片段的 ID。 replace(...)
method needs reference to fragment container view (in doc named containerViewId
). read doc carefully 用于正确的导航切换