【问题标题】:Setting a textview as button in recyclerview item in fragment将textview设置为片段中recyclerview项目中的按钮
【发布时间】:2021-08-07 03:26:18
【问题描述】:

现在我正在创建一个 android 应用程序。在我的应用程序中,我想在片段中的 RecyclerView 项中创建一个 TextView 作为按钮。所以我用这段代码来实现它。但它对我不起作用,错误来了。

这是我的 list_item_status_admin.xml 文件,这个 textview 设置为按钮。

 <TextView
                android:id="@+id/btn_approve_status"
                android:layout_width="85dp"
                android:layout_height="wrap_content"
                android:background="@drawable/black_shape"
                android:backgroundTint="#144A30"
                android:layout_margin="7dp"
                android:gravity="center"
                android:text="Approve"
                android:textColor="#F6F4F4">

            </TextView>

这是我的 fragment_one.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".pending_req_admin">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbarStyle="outsideOverlay"
        tools:listitem="@layout/item_status_admin"
        android:scrollbars="vertical"
        android:id="@+id/pending_recyclerview">

    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

这是错误

 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
        at com.example.work_home.pending_req_admin.onCreateView(pending_req_admin.java:51)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
        at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1971)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:311)
        at androidx.fragment.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:249)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
        at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
        at android.view.View.measure(View.java:22002)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:958)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:721)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2410)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1498)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1751)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
2021-08-07 08:24:08.185 28019-28019/com.example.work_home E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

所以如果你熟悉这个,请考虑一下,谢谢

这是我的java代码

public class pending_req_admin extends Fragment {
    View v;
    RecyclerView pending_req_RecycleView;
    // ArrayList<Model> listModel;
    //RecyclerViewAdapterSt recyclerViewAdapterSt;
    FirebaseAuth auth = FirebaseAuth.getInstance();
    FirebaseUser FUser = auth.getCurrentUser();
    String UserId = FUser.getUid();
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    FirestoreRecyclerAdapter adapter;
    TextView Btn_Approve_Status, Btn_Reject_Status;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment


        // Inflate the layout for this fragment
        v = inflater.inflate(R.layout.fragment_pending_req_admin, container, false);
        pending_req_RecycleView = v.findViewById(R.id.pending_recyclerview);
        Btn_Approve_Status = v.findViewById(R.id.btn_approve_status);
        Btn_Reject_Status = v.findViewById(R.id.btn_reject_status);

        //listModel = new ArrayList<>();
        // recyclerViewAdapterSt = new RecyclerViewAdapterSt(listModel);
        // statusRecycleView.setAdapter(recyclerViewAdapterSt);
        pending_req_RecycleView.setHasFixedSize(true);

        Query query = db.collection("users").document().collection("ApplyLeave");
        FirestoreRecyclerOptions<Model> options = new FirestoreRecyclerOptions.Builder<Model>()
                .setQuery(query, Model.class)
                .build();
        adapter = new FirestoreRecyclerAdapter<Model, pendingViewHolder>(options) {
            @NonNull
            @Override
            public pendingViewHolder onCreateViewHolder(@NonNull  ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_status_admin,parent,false);
                return new pendingViewHolder(v);
            }

            @Override
            protected void onBindViewHolder(@NonNull  pending_req_admin.pendingViewHolder holder, int position, @NonNull  Model model) {
                holder.p_reason.setText(model.getU_reason());
                holder.p_name.setText(model.getU_nameL());
                holder.p_selectLeave.setText(model.getU_select_leave());
                holder.p_leaveType.setText(model.getU_leave_type());
                holder.p_fromDate.setText(model.getU_from_date());
                holder.p_toDate.setText(model.getU_to_date());


                Btn_Approve_Status.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(getActivity(), "Leave Request Approved", Toast.LENGTH_SHORT).show();
                        Intent openSecondActivity = new Intent(pending_req_admin.this.getContext(), UserLeave.class);
                        startActivity(openSecondActivity);

                    }
                });

                Btn_Reject_Status.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(getActivity(), "Leave Request Rejected", Toast.LENGTH_SHORT).show();
                        Intent openSecondActivity = new Intent(pending_req_admin.this.getContext(), Home.class);
                        startActivity(openSecondActivity);

                    }
                });
            }
        };
        pending_req_RecycleView.setHasFixedSize(true);
        pending_req_RecycleView.setLayoutManager(new LinearLayoutManager(getActivity()));
        pending_req_RecycleView.setAdapter(adapter);

        return  v ;

    }

    private class pendingViewHolder extends RecyclerView.ViewHolder
    {
        TextView p_reason;
        TextView p_name;
        TextView p_selectLeave;
        TextView p_leaveType;
        TextView p_fromDate;
        TextView p_toDate;

        public pendingViewHolder(@NonNull  View itemView) {
            super(itemView);
            p_reason = itemView.findViewById(R.id.txt_reason_status);
            p_name = itemView.findViewById(R.id.txt_name_status);
            p_selectLeave = itemView.findViewById(R.id.txt_selectLeave_status);
            p_leaveType = itemView.findViewById(R.id.txt_leaveType_status);
            p_fromDate = itemView.findViewById(R.id.txt_fromDate_status);
            p_toDate = itemView.findViewById(R.id.txt_toDate_status);

        }
    }
    @Override
    public void onStart() {
        super.onStart();
        adapter.startListening();
    }

    @Override
    public void onStop() {
        super.onStop();
        adapter.stopListening();
    }
}

【问题讨论】:

  • 您似乎忘记分配 Textview Id。顺便请添加java代码。
  • 可以添加RecyclerView Adapter代码吗?
  • 请向我们展示您的代码,以便我们为您提供正确的帮助。在您的适配器和 ViewHolder 中显示代码。
  • 我将其添加到代码中
  • btn_approve_status 是recyclerview 的一项,不能在fragment 中为其添加点击监听。您必须在适配器中添加其点击侦听器。

标签: java android android-studio android-fragments


【解决方案1】:
  1. 创建一个适配器类。

  2. 将您的 list_item_status_admin.xml 布局扩展为 onCreateViewHolder()

                 @Override
                 public MovieListAdapter.Viewholder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
                     view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_status_admin, parent, false);
                     return new Viewholder(view);
                 }
    
  3. 将您的 TextView id 分配给适配器中的 ViewHolder() 类。

                 public class Viewholder extends RecyclerView.ViewHolder {
                     RecyclerView pending_req_RecycleView;
    
                     public Viewholder(@NonNull @NotNull View itemView) {
                         super(itemView);
                         pending_req_RecycleView = itemView.findViewById(R.id.CV_movieInfo);
                     }
                 }
    
  4. onBindViewHolder()中设置Btn_Approve_Status setOnClickListener()

                 @Override
                 public void onBindViewHolder(@NonNull @NotNull MovieListAdapter.Viewholder holder, int position) {
                     holder.Btn_Approve_Status.setOnClickListener(new View.OnClickListener() {
                         @Override
                         public void onClick(View v) {
                             Toast.makeText(getActivity(), "Leave Request Approved", Toast.LENGTH_SHORT).show();
                             Intent openSecondActivity = new Intent(pending_req_admin.this.getContext(), UserLeave.class);
                             startActivity(openSecondActivity);
    
                         }
                     });
                 }
    
  5. 最后,在你的 recyclerView 的pending_req_admin.java 片段中添加这个适配器类。

                 pending_req_RecycleView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                 pending_req_RecycleView.setAdapter(new YourAdaperclassName());
    

这是整个适配器类:

public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
                Context mcontext;
            
                public adapter(Context context) {
                    mcontext = context;
                }
            
                @NonNull
                @NotNull
                @Override
                public adapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
                    view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_status_admin, parent, false);
                    return new Viewholder(view);
                }
            
                @Override
                public void onBindViewHolder(@NonNull @NotNull adapter.ViewHolder holder, int position) {
                    holder.Btn_Approve_Status.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(mcontext, "Leave Request Approved", Toast.LENGTH_SHORT).show();
                            Intent openSecondActivity = new Intent(mcontext, UserLeave.class);
                            openSecondActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            mcontext.startActivity(openSecondActivity);
                        }
                    });
                }
            
                @Override
                public int getItemCount() {
                    return 0;
                }
            
                public class ViewHolder extends RecyclerView.ViewHolder {
                    RecyclerView pending_req_RecycleView;
            
                    public ViewHolder(@NonNull @NotNull View itemView) {
                        super(itemView);
                        pending_req_RecycleView = itemView.findViewById(R.id.CV_movieInfo);
                    }
                }
            }

注意:您必须在适配器构造函数中传递 List,或者只在适配器类中的 getItemCount() 中提供静态大小。

【讨论】:

  • 我还在学习android编程,所以不要误解我,我可以告诉你,我已经在我的代码中设置了onBindViewHolder。所以我应该用你在这里提到的代码再次添加它吗???
  • 我现在在我的代码中有进一步的开发,你能告诉我如何调整这个解决方案吗?我在上面编辑了我的 java 代码。
【解决方案2】:

btn_reject_status 存在于 list_item_status_admin.xml 中,并且您正在 Fragment 中添加项目布局视图的点击侦听器。

需要创建自定义适配器并将该适配器设置为您的回收站视图

以下示例代码供参考:

适配器类:

public class RecyclerMainAdapter extends FirestoreRecyclerAdapter<MainBeen, RecyclerMainAdapter.ViewHolder> {

   private RecyclerViewItemClick recyclerViewItemClick;

    public RecyclerMainAdapter(@NonNull FirestoreRecyclerOptions<MainBeen> options, RecyclerViewItemClick recyclerViewItemClick) {
        super(options);
        this.recyclerViewItemClick = recyclerViewItemClick;
    }
    @Override
    protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull MainBeen model) {
        holder.btnApproveStatus.setText(model.getITEM_DESCRIPTION());
        holder.btnApproveStatus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                recyclerViewItemClick.onTextViewClick(position);
            }
        });
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_status_admin,
                parent, false);
        return new ViewHolder(v);
    }
    static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView btnApproveStatus;
        public ViewHolder(View itemView) {
            super(itemView);
            btnApproveStatus = itemView.findViewById(R.id.btn_approve_status);
        }
    }

    
    /*Interface for communicating Adapter to Actvity/Fragment*/
    public  interface RecyclerViewItemClick{
        void onTextViewClick(int position);
    }
}

上面代码中MainBeen是Model Class,你需要根据自己的需求改变这个class。

如何在 Fragment 中将适配器设置为 RecyclerView:

RecyclerMainAdapter recyclerMainAdapter = new RecyclerMainAdapter(mainBeenOptions, new RecyclerMainAdapter.RecyclerViewItemClick() {
            @Override
            public void onTextViewClick(int position) {
                // Handling click on recyclerview item textview
                Toast.makeText(getActivity(), "Leave Request Approved", Toast.LENGTH_SHORT).show();
                Intent openSecondActivity = new Intent(getContext(), UserLeave.class);
                startActivity(openSecondActivity);
            }
        });
        pending_req_RecycleView.setLayoutManager(new LinearLayoutManager(getContent()));
        pending_req_RecycleView.setAdapter(recyclerMainAdapter);

有关 RecyclerView 适配器的更多信息,请查看以下链接:FirestorerecycleradapterRecyclerView.Adapter

【讨论】:

  • 我认为他现在不想对 Firebase 做任何事情,他只想在回收站视图中添加 textView 作为按钮。所以,他只需要扩展 RecyclerView.Adapter
  • 他在 Fragment 中添加了FirestoreRecyclerAdapter,这就是我在示例中包含FirestoreRecyclerAdapter 的原因
猜你喜欢
  • 2016-02-23
  • 2016-08-16
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 2018-01-10
相关资源
最近更新 更多