如何在 Fragment 中使用 Recycler View [重复]

Posted

技术标签:

【中文标题】如何在 Fragment 中使用 Recycler View [重复]【英文标题】:How to Use Recycler View in Fragment [duplicate] 【发布时间】:2021-07-19 02:04:12 【问题描述】:

马斯塔

我正在尝试从我的 FireBase 实时数据库中读取数据。我在 Fragment 中使用 Recycler 视图来阅读它。当我编码时,没有错误的迹象。但是当我尝试运行代码时,它会显示如下错误:

2021-04-25 20:37:21.060 20896-20896/com.kuplay.storingdata E/androidRuntime: FATAL EXCEPTION: main
Process: com.kuplay.storingdata, PID: 20896
java.lang.ClassCastException: com.kuplay.storingdata.ui.MainActivity cannot be cast to com.kuplay.storingdata.Adapter.RecyclerViewAdapter$dataListener
    at com.kuplay.storingdata.Adapter.RecyclerViewAdapter.<init>(RecyclerViewAdapter.java:39)
    at com.kuplay.storingdata.Fragment.data.DataFragment$1.onDataChange(DataFragment.java:80)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
    at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
    at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:239)
    at android.app.ActivityThread.main(ActivityThread.java:8179)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)

我尝试了很多方法并尝试从谷歌搜索许多参考。但它不起作用。

任何机构都可以帮我解决这个错误...因为我还是个菜鸟。

这是我的代码:

DataFragment.java

package com.kuplay.storingdata.Fragment.data;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.kuplay.storingdata.Adapter.RecyclerViewAdapter;
import com.kuplay.storingdata.Model.data_finance;
import com.kuplay.storingdata.R;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Objects;

public class DataFragment extends Fragment 
    private RecyclerView recyclerView;
    private RecyclerViewAdapter adapter;
    private RecyclerView.LayoutManager layoutManager;

    private FirebaseAuth auth;
    private DatabaseReference reference;
    private ArrayList<data_finance> dFinance;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        View root = inflater.inflate(R.layout.fragment_data, container, false);
        recyclerView = root.findViewById(R.id.data_list);
        auth = FirebaseAuth.getInstance();

        MyRecyclerView();
        GetData();
        return root;
    

    private void MyRecyclerView()
        layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);

        DividerItemDecoration itemDecoration = new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL);
        itemDecoration.setDrawable(Objects.requireNonNull(ContextCompat.getDrawable(getActivity(), R.drawable.line)));
        recyclerView.addItemDecoration(itemDecoration);
    

    private void GetData()
        reference = FirebaseDatabase.getInstance().getReference();
        reference.child("Finance");
        reference.child(Objects.requireNonNull(auth.getUid()));
        reference.child("Data");
        reference.addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NotNull DataSnapshot dataSnapshot) 
                //Inisialisasi ArrayList
                dFinance = new ArrayList<>();

                for (DataSnapshot snapshot : dataSnapshot.getChildren()) 
                    data_finance finance = snapshot.getValue(data_finance.class);

                    assert finance != null;
                    finance.setId(snapshot.getKey());
                    dFinance.add(finance);
                

                adapter = new RecyclerViewAdapter(dFinance, getActivity());
                recyclerView.setAdapter(adapter);
            

            @Override
            public void onCancelled(@NotNull DatabaseError databaseError) 

                Toast.makeText(getActivity(), "Data Gagal Dimuat", Toast.LENGTH_LONG).show();
                Log.e("MyListActivity", databaseError.getDetails() + " " + databaseError.getMessage());
            
        );
    

RecyclerViewAdapter.java

package com.kuplay.storingdata.Adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;

import com.kuplay.storingdata.Model.data_finance;
import com.kuplay.storingdata.R;
import com.kuplay.storingdata.ui.updateData;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>

    private ArrayList<data_finance> listFinance;
    private Context context;

    public interface dataListener
        void onDeleteData(data_finance data, int position);
    

    dataListener listener;

    public RecyclerViewAdapter(ArrayList<data_finance> listFinance, Context context) 
        this.listFinance = listFinance;
        this.context = context;
        listener = (dataListener) context;
    

    static class ViewHolder extends RecyclerView.ViewHolder

        private TextView Nama;
        private TextView Pemasukan;
        private TextView Pengeluaran;
        private TextView Waktu;
        private LinearLayout lst_item;

        ViewHolder(View itemView) 
            super(itemView);

            Nama = itemView.findViewById(R.id.tbl_nama);
            Pemasukan = itemView.findViewById(R.id.tbl_pemasukan);
            Pengeluaran = itemView.findViewById(R.id.tbl_pengeluaran);
            Waktu = itemView.findViewById(R.id.tbl_waktu);
            LinearLayout tbl_header = itemView.findViewById(R.id.tbl_header);
            lst_item = itemView.findViewById(R.id.lst_item);
        
    

    @NotNull
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
        View V = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_design, parent, false);
        return new ViewHolder(V);
    

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) 
        final String Nama = listFinance.get(position).getNama();
        final String Pemasukan = listFinance.get(position).getPemasukan();
        final String Pengeluaran = listFinance.get(position).getPengeluaran();
        final String Waktu = listFinance.get(position).getWaktu();

        holder.Nama.setText(Nama);
        holder.Pemasukan.setText(Pemasukan);
        holder.Pengeluaran.setText(Pengeluaran);
        holder.Waktu.setText(Waktu);

        holder.lst_item.setOnLongClickListener(new View.OnLongClickListener() 
            @Override
            public boolean onLongClick(final View view) 
                final String[] action = "Update", "Delete";
                AlertDialog.Builder alert = new AlertDialog.Builder(view.getContext());
                alert.setItems(action,  new DialogInterface.OnClickListener() 
                    @Override
                    public void onClick(DialogInterface dialog, int i) 
                        switch (i)
                            case 0:
                                Bundle bundle = new Bundle();
                                bundle.putString("dataNama", listFinance.get(position).getNama());
                                bundle.putString("dataPemasukan", listFinance.get(position).getPemasukan());
                                bundle.putString("dataPengeluaran", listFinance.get(position).getPengeluaran());
                                bundle.putString("dataWaktu", listFinance.get(position).getWaktu());
                                bundle.putString("getPrimaryKey", listFinance.get(position).getId());
                                Intent intent = new Intent(view.getContext(), updateData.class);
                                intent.putExtras(bundle);
                                context.startActivity(intent);
                                break;
                            case 1:
                                listener.onDeleteData(listFinance.get(position), position);
                                break;
                        
                    
                );
                alert.create();
                alert.show();
                return true;
            
        );
    

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


MainActivity.java

package com.kuplay.storingdata.ui;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;
import android.widget.Toast;

import com.firebase.ui.auth.AuthUI;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.auth.FirebaseAuth;
import com.kuplay.storingdata.Fragment.input.InputFragment;
import com.kuplay.storingdata.R;

import androidx.annotation.NonNull;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

public class MainActivity extends AppCompatActivity 

    private AppBarConfiguration mAppBarConfiguration;
    public FirebaseAuth auth;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);

        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_input, R.id.nav_data, R.id.nav_cashflow)
                .setDrawerLayout(drawer)
                .build();

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    


    @Override
    public boolean onCreateOptionsMenu(Menu menu) 

        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) 
        switch (item.getItemId())
            case R.id.logout:
                AuthUI.getInstance()
                        .signOut(this)
                        .addOnCompleteListener(new OnCompleteListener() 
                            @Override
                            public void onComplete(@NonNull Task task) 
                                Toast.makeText(MainActivity.this, "Logout Berhasil", Toast.LENGTH_SHORT).show();
                                Intent home = new Intent(MainActivity.this, StartActivity.class);
                                startActivity(home);
                                finish();
                            
                        );
                return true;
        
        return false;
    

    @Override
    public boolean onSupportNavigateUp() 
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    

请有人帮我解决这个错误;(

【问题讨论】:

【参考方案1】:
 adapter = new RecyclerViewAdapter(dFinance, getActivity());

你在 RecyclerViewAdapter 中设置上下文变量,我看到的就是 MainActivity (getActivity())。

public RecyclerViewAdapter(ArrayList<data_finance> listFinance, Context context) 
    this.listFinance = listFinance;
    this.context = context;
    listener = (dataListener) context;

在这里,您尝试将上下文 (MainActivity) 转换为 dataListener 类型,这是错误“java.lang.ClassCastException: com.kuplay.storingdata.ui.MainActivity 无法转换为 com.kuplay”所指示的不匹配.storingdata.Adapter.RecyclerViewAdapter$dataListener"

你不能让 MainActivity 像 in 那样实现 dataListener 吗?

class MainActivity ... implements RecyclerViewAdapter.dataListener

然后简单地覆盖接口函数?

【讨论】:

【参考方案2】:

MainActivity 没有实现 MainActivity dataListener 接口,但是您正在将活动投射到适配器中的 dataListener ,这实际上是错误的。您可以在 MainActivity 或 Fragment 中实现 dataListener 并传递实际参数。

【讨论】:

以上是关于如何在 Fragment 中使用 Recycler View [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Recycler视图在android studio中未显示一张卡片视图

如何使用 youtube data api v3 中的 nextPageToken 在 android recycler 视图中加载更多视频

如何在 JSON 的 Recycler 视图中显示特定类别

Recycler View重复,如何查看一次

如何使用 Recycler View 的长按位置获取 SQLite 列值?

我想使用 GeoFire 在 android 中填充 Firebase Recycler View