Hello. I use the SwipeRecyclerViewAdapter library. Attached it to RecyclerView , each line of which displays CardView . Animation and swipe work great.

Problem # 1: If you put an addOnItemTouchListener in the body of the ReyclerView fragment and ask it to do something, then this action works correctly. If svaypnut (shift CardView), then a button appears. If you click on it, then instead of the task of this button, the action that was set on my ReyclerView's addOnItemTouchListener is performed. In other words, the touch leaf overlaps the exit button.

Possible solution: somehow check whether CardView is shifted now or not. And starting from this, turn on / off the item touchscreen so that it does not block the leaving element.

Problem number 2: Clicking can be processed in the body of the adapter, everything seems to work fine here too, but when the method is called (which replaces A fragment with A fragment), java.lang.NullPointerException crashes from A fragment. I tried to understand what the problem was based on an article from Habr about these exceptions, but it did not lead to anything. Here is the code for the fragmentation method I am trying to call:

  public void perehod(){ FragmentTransaction ftrans = getFragmentManager().beginTransaction(); SettingsFilter settingsFilter = new SettingsFilter(); ftrans.replace(R.id.content_frame, settingsFilter); ftrans.addToBackStack(null); ftrans.commit(); } 

Here is the adapter code:

 import android.content.Context; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import com.daimajia.swipe.SwipeLayout; import com.daimajia.swipe.adapters.RecyclerSwipeAdapter; import java.util.ArrayList; import com.myApp.R; import com.myApp.frags.FilterFrag; public class SwipeRecyclerViewAdapter extends RecyclerSwipeAdapter<SwipeRecyclerViewAdapter.SimpleViewHolder> { FilterFrag filterFrag; private Context mContext; private static ArrayList<String> region; public static String myItem; static FilterFrag myFilter; public SwipeRecyclerViewAdapter(Context context, ArrayList<String> dataset) { this.mContext = context; region = dataset; } @Override public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.swipe_row_item, parent, false); return new SimpleViewHolder(view); } @Override public void onBindViewHolder(final SimpleViewHolder viewHolder, final int position) { final String item = region.get(position); viewHolder.mTextView.setText(region.get(position)); viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut); viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper1)); viewHolder.swipeLayout.setLeftSwipeEnabled(false); viewHolder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() { @Override public void onClose(SwipeLayout layout) { //when the SurfaceView totally cover the BottomView. } @Override public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) { //you are swiping. } @Override public void onStartOpen(SwipeLayout layout) { } @Override public void onOpen(SwipeLayout layout) { //when the BottomView totally show. } @Override public void onStartClose(SwipeLayout layout) { } @Override public void onHandRelease(SwipeLayout layout, float xvel, float yvel) { } }); viewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { myItem = region.get(position); ///////////////////////////////////////////////////////////// //-------------------Здесь вызываю метод----------------------- myFilter.perehod(); //--------------------------------------------------------- ///////////////////////////////////////////////////////////// } }); viewHolder.btnLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "Клик на выезжающем элементе", Toast.LENGTH_SHORT).show(); } }); mItemManger.bindView(viewHolder.itemView, position); } @Override public int getItemCount() { return region.size(); } @Override public int getSwipeLayoutResourceId(int position) { return R.id.swipe; } public static class SimpleViewHolder extends RecyclerView.ViewHolder { SwipeLayout swipeLayout; public TextView mTextView; ImageButton btnLocation; public SimpleViewHolder(View itemView) { super(itemView); swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe); mTextView = (TextView) itemView.findViewById(R.id.filter_recycler_tv); btnLocation = (ImageButton) itemView.findViewById(R.id.btnLocation); } } public static String getValue(int position) { return region.get(position); } } 

Here is the log:

04-16 19: 06: 54.250 5320-5320 / com.myApp E / AndroidRuntime: FATAL EXCEPTION: main java.lang.NullPointerException at com.myApp.Adapters.SwipeRecyclerViewAdapter $ 2.onClick (SwipeRecyclerViewAdapter.java:117) at android.view .View.performClick (View.java:4204) at android.view.View $ PerformClick.run (View.java:17355) at android.os.Handler.handleCallback (Handler.java:725) at android.os.Handler. dispatchMessage (Handler.java:92) at android.os.Looper.loop (Looper.java:137) at android.app.ActivityThread.main (ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative (Native Method) at java.lang.reflect.Method.invoke (Method.java sources11) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:793) at com.android.internal.os.ZygoteInit .main (ZygoteInit.java Dep60) at dalvik.system.NativeStart.main (Native Method)

    1 answer 1

    To solve problem 1) try to do so.

     public class SingleTapGestureDetector implements GestureDetector.OnGestureListener { @Override public boolean onDown(MotionEvent e) { return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } } 

    Add it as a property in the adapter private GestureDetector gestureDetector; , then initialize it in the adapter's constructor. gestureDetector = new GestureDetector(mContext, new SingleTapGestureDetector()); and then use it in setOnTouchListener

     holder.itemView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (gestureDetector.onTouchEvent(event)) { //item touch action } return false; } }); 

    2) why don't you pass the listener to the adapter and call the listener method, for example, so listener.perehod() , and let the fragment already implement this listener. As far as I understand, this adapter is declared in the fragment that you currently have as a static field in the adapter. The adapter should not contain links to fragments, it is responsible only for the content of recyclerView. And you have initialized static FilterFrag myFilter; ?

    • Thanks for the answer. Could you explain a little about the second solution? I don't seem to have references to the fragment, I just call the method from the fragment (which changes the fragments). FilterFrag (this is a fragment) I have initialized in the adapter. But when calling myFilter.perehod(); crashes. Yes, the adapter is declared in the body of the fragment and fills it. - ivanovd422
    • from a piece of code for your adapter, I can conclude that myFilter is null, because there is no place for you to initialize it. static FilterFrag myFilter; This is a link to the fragment and is not initialized - Yury Pashkov