如何使用recyclerView将onClick添加到Fragment

时间:2017-11-07 16:10:30

标签: android android-recyclerview onclick

我有以下代码来制作网络摄像头并显示数据列表。 使用RecyclerView可以正确显示列表,但是我无法通过触摸行来获得onclick。

我已经从onclick中注销了该位置并且工作正常,但应用程序因为onClick变量尚未实例化而与NPE崩溃。

我知道我需要用

做到这一点
mAdapter.setOnClick(this);

但我不知道该把它放在哪里。

link

如何在片段中设置onclick。上面的帖子使用的是Activity,而我正在使用片段。

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.List;

/**
 * Created by MatthewW on 01/11/2017.
 */

public class LoneworkerGetRotaActivityFragment extends Fragment {

    private static final String TAG = LoneworkerGetRotaActivityFragment.class.getSimpleName();
    AppObj appObj;
    List<Visit> mVisitList;
    String URL;
    String companyID;
    String ID2;
    String userID;

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;






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

        appObj = (AppObj)getActivity().getApplication();
        URL = appObj.dbModel.getCompanyUrl();
        Log.e(TAG, "URL = " + URL);
        companyID = appObj.dbModel.getCompanyID();
        ID2 = appObj.dbModel.getCompanyWebServiceGuid();
        userID = appObj.dbModel.getUserID();



    }//end of onCreate






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


        LayoutInflater lf = getActivity().getLayoutInflater();
        View view = lf.inflate(R.layout.l_w_get_rota_activity_fragment, container, false);

        mRecyclerView = (RecyclerView) view.findViewById(R.id.get_rota_recycler_view);



        sendRequest();

        return view;


    }




    private void sendRequest(){

        //https://CFTest.carefreeapp.co.uk/roadrunner.asmx/GetRotaHours?CarerID=36&RotaDate=2-Nov-2017
        //https://CFTest.carefreeapp.co.uk/roadrunner.asmx/RRGetRota?ID1=900&ID2=9d817606-9194-4528-84b4-028e5aa90330&CarerID=36&RotaDate=2-Nov-2017

        StringRequest stringRequest = new StringRequest(URL + "/roadrunner.asmx/RRGetRota?ID1=" + companyID + "&ID2=" + ID2 + "&CarerID=" + userID + "&RotaDate=" + "2-Nov-2017",
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //success - parse rota

                        DomParser dp = new DomParser(getActivity());
                        mVisitList = dp.parseUserRota(response);
                        Log.e(TAG, "mVisitList has size of " + mVisitList.size());

                        // use this setting to improve performance if you know that changes
                        // in content do not change the layout size of the RecyclerView
                        mRecyclerView.setHasFixedSize(true);

                        // use a linear layout manager
                        mLayoutManager = new LinearLayoutManager(getActivity());
                        mRecyclerView.setLayoutManager(mLayoutManager);

                        // specify an adapter (see also next example)
                        mAdapter = new MyAdapter(mVisitList);
                        mRecyclerView.setAdapter(mAdapter);








                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
                    }
                });


        RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.add(stringRequest);
    }




    public interface OnItemClicked {
        void onItemClick(int position);
    }

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>  {


        //declare interface
        OnItemClicked onClick;



        public class ViewHolder extends RecyclerView.ViewHolder {

            public TextView tvStartDate;
            public TextView tvEndDate;
            public TextView tvDuration;
            public TextView tvClientForeName;
            public TextView tvClientSurName;


            public ViewHolder(View v) {
                super(v);
                tvStartDate = (TextView) v.findViewById(R.id.get_rota_startdate);
                tvEndDate = (TextView) v.findViewById(R.id.get_rota_enddate);
                tvDuration = (TextView) v.findViewById(R.id.get_rota_duration);
                tvClientForeName = (TextView) v.findViewById(R.id.get_rota_forename);
                tvClientSurName = (TextView) v.findViewById(R.id.get_rota_surname);
            }




        }//end of viewholder





        // Provide a suitable constructor (depends on the kind of dataset)
        public MyAdapter(List<Visit> myVisitList) {
            mVisitList = myVisitList;
        }

        // Create new views (invoked by the layout manager)
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {


            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.get_rota_row_layout, parent, false);

            return new ViewHolder(v);
        }

        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element

            final int pos = position;

            DateTimeFormatter fmt = DateTimeFormat.forPattern("H:mm");


            String strStartDate = mVisitList.get(position).getStartDate();
            DateTime dtStartTime = new DateTime(strStartDate);
            String formattedStartTime = fmt.print(dtStartTime);
            holder.tvStartDate.setText(formattedStartTime);

            String strEndDate = mVisitList.get(position).getEndDate();
            DateTime dtEndTime = new DateTime(strEndDate);
            String formattedEndTime = fmt.print(dtEndTime);
            holder.tvEndDate.setText(formattedEndTime);

            holder.tvDuration.setText(mVisitList.get(position).getDuration());
            holder.tvClientForeName.setText(mVisitList.get(position).getClientForename());
            holder.tvClientSurName.setText(mVisitList.get(position).getClientSurname());




            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e(TAG, "onclick pos = " + pos);
                    onClick.onItemClick(pos);

                }
            });



        }

        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return mVisitList.size();
        }


        public void setOnClick(OnItemClicked onClick)
        {
            this.onClick=onClick;
        }

    }//end of adapter class









}//end of class

 11-07 15:53:01.268 2701-2701/loneworker.carefreegroup.com.loneworker E/LoneworkerGetRotaActivityFragment: onclick pos = 1
11-07 15:53:01.269 2701-2701/loneworker.carefreegroup.com.loneworker D/AndroidRuntime: Shutting down VM


                                                                                       --------- beginning of crash
11-07 15:53:01.273 2701-2701/loneworker.carefreegroup.com.loneworker E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                       Process: loneworker.carefreegroup.com.loneworker, PID: 2701
                                                                                       java.lang.NullPointerException: Attempt to invoke interface method 'void loneworker.carefreegroup.com.loneworker.LoneworkerGetRotaActivityFragment$OnItemClicked.onItemClick(int)' on a null object reference
                                                                                           at loneworker.carefreegroup.com.loneworker.LoneworkerGetRotaActivityFragment$MyAdapter$1.onClick(LoneworkerGetRotaActivityFragment.java:230)
                                                                                           at android.view.View.performClick(View.java:6213)
                                                                                           at android.view.View$PerformClick.run(View.java:23645)
                                                                                           at android.os.Handler.handleCallback(Handler.java:751)
                                                                                           at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                           at android.os.Looper.loop(Looper.java:154)
                                                                                           at android.app.ActivityThread.main(ActivityThread.java:6692)
                                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

2 个答案:

答案 0 :(得分:1)

在创建MyAdater对象后设置OnItemClicked Lister,如下所示

// specify an adapter (see also next example)
 mAdapter = new MyAdapter(mVisitList); // after this line

 mAdapter.setOnClick(new OnItemClicked() {
            @Override
            public void onItemClick(int position) {

            }
        });

答案 1 :(得分:0)

我决定使用RecyclerTouchListener以不同的方式做到这一点。

mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(),
                                mRecyclerView, new ClickListener() {

                            @Override
                            public void onClick(View view, final int position) {

                                Log.e(TAG, "Short press on position :" + position);

                                TextView  tvDuration = (TextView) view.findViewById(R.id.get_rota_duration);
                                String strDuration = tvDuration.getText().toString();

                                try{

                                    Integer.parseInt(strDuration);

                                    //TODO create a visit from the data from webcall (in appObj) for info passed to email, text etc

                                    Intent i = new Intent(getActivity(), LoneworkerActivity3.class);
                                    i.putExtra("duration", strDuration);
                                    startActivity(i);

                                }catch (Exception e){
                                    Toast.makeText(getActivity(), "The LoneWorker duration is not valid", Toast.LENGTH_LONG).show();
                                }





                            }

                            @Override
                            public void onLongClick(View view, int position) {

                                Log.e(TAG, "Long press on position :" + position);
                            }

                        }));

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {






        public class ViewHolder extends RecyclerView.ViewHolder {

            public TextView tvStartDate;
            public TextView tvEndDate;
            public TextView tvDuration;
            public TextView tvClientForeName;
            public TextView tvClientSurName;


            public ViewHolder(View v) {
                super(v);
                tvStartDate = (TextView) v.findViewById(R.id.get_rota_startdate);
                tvEndDate = (TextView) v.findViewById(R.id.get_rota_enddate);
                tvDuration = (TextView) v.findViewById(R.id.get_rota_duration);
                tvClientForeName = (TextView) v.findViewById(R.id.get_rota_forename);
                tvClientSurName = (TextView) v.findViewById(R.id.get_rota_surname);
            }




        }//end of viewholder





        // Provide a suitable constructor (depends on the kind of dataset)
        public MyAdapter(List<Visit> myVisitList) {
            mVisitList = myVisitList;
        }

        // Create new views (invoked by the layout manager)
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {


            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.get_rota_row_layout, parent, false);

            return new ViewHolder(v);
        }

        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element

            final int pos = position;

            DateTimeFormatter fmt = DateTimeFormat.forPattern("H:mm");


            String strStartDate = mVisitList.get(position).getStartDate();
            DateTime dtStartTime = new DateTime(strStartDate);
            String formattedStartTime = fmt.print(dtStartTime);
            holder.tvStartDate.setText(formattedStartTime);

            String strEndDate = mVisitList.get(position).getEndDate();
            DateTime dtEndTime = new DateTime(strEndDate);
            String formattedEndTime = fmt.print(dtEndTime);
            holder.tvEndDate.setText(formattedEndTime);

            holder.tvDuration.setText(mVisitList.get(position).getDuration());
            holder.tvClientForeName.setText(mVisitList.get(position).getClientForename());
            holder.tvClientSurName.setText(mVisitList.get(position).getClientSurname());








        }

        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return mVisitList.size();
        }



    }//end of adapter class

    public interface ClickListener{
        public void onClick(View view,int position);
        public void onLongClick(View view,int position);
    }


    class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{

        private ClickListener clicklistener;
        private GestureDetector gestureDetector;

        public RecyclerTouchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener){

            this.clicklistener=clicklistener;
            gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return true;
                }

                @Override
                public void onLongPress(MotionEvent e) {
                    View child=recycleView.findChildViewUnder(e.getX(),e.getY());
                    if(child!=null && clicklistener!=null){
                        clicklistener.onLongClick(child,recycleView.getChildAdapterPosition(child));
                    }
                }
            });
        }

        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            View child=rv.findChildViewUnder(e.getX(),e.getY());
            if(child!=null && clicklistener!=null && gestureDetector.onTouchEvent(e)){
                clicklistener.onClick(child,rv.getChildAdapterPosition(child));
            }

            return false;
        }

        @Override
        public void onTouchEvent(RecyclerView rv, MotionEvent e) {

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }
    }