2017-11-07 8 views
0

Ich habe den folgenden Code, der einen Webcall erstellt und eine Liste von Daten anzeigt. Die Liste wird korrekt mit RecyclerView angezeigt, aber ich kann keinen onclick erreichen, wenn ich eine Zeile berühre.wie man onClick to Fragment mit recyclerView hinzufügen

Ich habe die Position vom onclick abgemeldet und das funktioniert gut, aber die App stürzt mit einer NPE ab, weil die onClick-Variable nicht instanziiert wurde.

Ich weiß, ich brauche diese

mAdapter.setOnClick(this); 

mit

zu tun.

aber ich bin mir nicht sicher, wo ich es hinstellen soll.

link

Wie kann ich das Onclick in meinem Fragment gesetzt. Der obige Beitrag verwendet eine Aktivität, während ich ein Fragment verwende.

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) 

Antwort

0

Ich beschloss, es eine andere Art und Weise mit RecyclerTouchListener zu tun.

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) { 

     } 
    } 
0

Set OnItemClicked Lister nach der Erstellung von MyAdater Objekt wie unter

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

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

      } 
     }); 
+0

es sagt, dass setOnClick nicht aufgelöst werden kann. – turtleboy

+0

setOnClick-Methode existiert auf MyAdapter oder nicht? – Munir

+0

ja, es ist die letzte Methode am Ende – turtleboy

Verwandte Themen