web-dev-qa-db-ja.com

ViewPagerでCardViewを有効にする方法

ViewPagerでCardViewを使用してみましたが、CardViewを左右にスワイプするたびに次の画面に移動します。その時、カード自体を削除してほしい。現在、スタンドアロンとしては両方とも正常に機能していますが、組み合わせると、ビューページャーのみが機能し、カードワイプは閉じません。

以下のコードでViewPagerを無効にしようとしましたが、このコードはCardViewスワイプジェスチャも無効にします。 CardViewのみにジェスチャーを設定するにはどうすればよいですか。2枚のカード間をスワイプすると、カード要素に接続されていないため、ViewPagerが表示されます。

または、ViewPagerを完全に無効にしてボタンとして使用し、CardViewでスワイプを有効にします。私は本当にどんな助けにも感謝します。前もって感謝します。

参考:ViewPagerでAndroid_horizo​​ntal_listviewを試しましたが、これは問題なく動作し、まったく同じです。

ViewPagerの場合:

mPager.setOnTouchListener(new OnTouchListener()
{           
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        return true;
    }
});

CardViewの場合:

SwipeableRecyclerViewTouchListener swipeTouchListener =

new SwipeableRecyclerViewTouchListener(mRecyclerView,
    new SwipeableRecyclerViewTouchListener.SwipeListener() {
        @Override
        public boolean canSwipe(int position) {
            return true;
        }

        @Override
        public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
            for (int position : reverseSortedPositions) {
                mItems.remove(position);
                mAdapter.notifyItemRemoved(position);
            }
            mAdapter.notifyDataSetChanged();
        }

        @Override
        public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
            for (int position : reverseSortedPositions) {
                mItems.remove(position);
                mAdapter.notifyItemRemoved(position);
            }
            mAdapter.notifyDataSetChanged();
        }
    });

mRecyclerView.addOnItemTouchListener(swipeTouchListener);

Mainactivity.Java

public class MainActivity extends Activity implements ActionBar.TabListener {


    ViewPager vp;
    View viewpager_layout_1;
    View viewpager_layout_2;
    View viewpager_layout_3;
    ActionBar.Tab tab_1;
    ActionBar.Tab tab_2;
    ActionBar.Tab tab_3;
    ActionBar bar;
    /////
    String jsonstring1;
    CardViewAdapter spinnerArray;
    ImageLoader imageLoader = ImageLoader.getInstance();//
    DisplayImageOptions options;
    ArrayList<HashMap<String, String>> array_list1;
    RecyclerView recyclerView;
    RelativeLayout re1;
    private Context mContext;

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

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        mContext = this;


        viewpager_layout_1 = new View(mContext);
        viewpager_layout_1 = getLayoutInflater().inflate(R.layout.sample1, null);


        viewpager_layout_3 = new View(mContext);
        viewpager_layout_3 = getLayoutInflater().inflate(R.layout.sample2, null);


        viewpager_layout_2 = new View(mContext);
        viewpager_layout_2 = getLayoutInflater().inflate(R.layout.sample3, null);


        vp = (ViewPager) findViewById(R.id.vp);
        bar = getActionBar();


        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        bar.setDisplayShowTitleEnabled(false);
        bar.setDisplayShowHomeEnabled(false);

        Vector<View> pages = new Vector<View>();

        pages.add(viewpager_layout_1);
        pages.add(viewpager_layout_3);
        pages.add(viewpager_layout_2);

        CustomPagerAdapter adapter = new CustomPagerAdapter(mContext, pages);
        vp.setAdapter(adapter);

        vp.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {

                bar.setSelectedNavigationItem(position);
            }
        });

        tab_1 = bar.newTab();
        tab_1.setCustomView(R.layout.tab_layout_1);
        tab_1.setTabListener(this);
        bar.addTab(tab_1);


        tab_2 = bar.newTab();
        tab_2.setCustomView(R.layout.tab_layout_2);
        tab_2.setTabListener(this);
        bar.addTab(tab_2);


        tab_3 = bar.newTab();
        tab_3.setCustomView(R.layout.tab_layout_3);
        tab_3.setTabListener(this);
        bar.addTab(tab_3);


        ////


        imageLoader.init(ImageLoaderConfiguration.createDefault(MainActivity.this));


        jsonstring1 = "[{\"category\":\"1\",\"no\":\"1\",\"image\":\"http://upload.wikimedia.org/wikipedia/commons/c/c3/Jordan_by_Lipofsky_16577.jpg\"},{\"category\":\"2\",\"no\":\"2\",\"image\":\"http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Basketball_World_Cup_2014.jpg/800px-Basketball_World_Cup_2014.jpg\"},{\"category\":\"3\",\"no\":\"3\",\"image\":\"http://upload.wikimedia.org/wikipedia/commons/4/4e/Basketball_Goal.jpg\"},{\"category\":\"4\",\"no\":\"4\",\"image\":\"http://upload.wikimedia.org/wikipedia/commons/1/10/Basketball_through_hoop.jpg\"}]";

        //////////

        array_list1 = new ArrayList<HashMap<String, String>>();
        JSONArray arr = null;
        try {
            arr = new JSONArray(jsonstring1);
            for (int i = 0; i < arr.length(); i++) {
                JSONObject e1 = arr.getJSONObject(i);
                String category = e1.getString("category").trim();
                String no = e1.getString("no").trim();
                String image = e1.getString("image").trim();

                HashMap<String, String> map = new HashMap<String, String>();
                map.put("category", category);
                map.put("no", no);
                map.put("image", image);
                // adding HashList to ArrayList
                array_list1.add(map);
            }


        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        OnItemTouchListener itemTouchListener = new OnItemTouchListener() {
            @Override
            public void onCardViewTap(View view, int position) {
                Toast.makeText(MainActivity.this, "Tapped " + array_list1.get(position), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onButton1Click(View view, int position) {
                Toast.makeText(MainActivity.this, "Clicked Button1 in " + array_list1.get(position), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onButton2Click(View view, int position) {
                Toast.makeText(MainActivity.this, "Clicked Button2 in " + array_list1.get(position), Toast.LENGTH_SHORT).show();
            }
        };

        spinnerArray = new CardViewAdapter(itemTouchListener, MainActivity.this, array_list1);
        recyclerView = (RecyclerView) viewpager_layout_3.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        SlideInBottomAnimationAdapter alphaAdapter = new SlideInBottomAnimationAdapter(spinnerArray);
        ScaleInAnimationAdapter alphaAdapter2 = new ScaleInAnimationAdapter(alphaAdapter);
        final AlphaInAnimationAdapter alphaAdapter3 = new AlphaInAnimationAdapter(alphaAdapter2);
        alphaAdapter3.setDuration(500);
        alphaAdapter3.setFirstOnly(true);
        recyclerView.setAdapter(alphaAdapter3);


        final SwipeableRecyclerViewTouchListener swipeTouchListener =
                new SwipeableRecyclerViewTouchListener(recyclerView,
                        new SwipeableRecyclerViewTouchListener.SwipeListener() {
                            @Override
                            public boolean canSwipe(int position) {
                                return true;
                            }


                            @Override
                            public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
                                for (int position : reverseSortedPositions) {
//                                    mItems.remove(position);
                                    Toast.makeText(MainActivity.this, array_list1.get(position) + " swiped left", Toast.LENGTH_SHORT).show();
                                    array_list1.remove(position);
                                    alphaAdapter3.notifyItemRemoved(position);
                                }
                                alphaAdapter3.notifyDataSetChanged();
                            }

                            @Override
                            public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
                                for (int position : reverseSortedPositions) {
//
                                    Toast.makeText(MainActivity.this, array_list1.get(position) + " swiped right", Toast.LENGTH_SHORT).show();
                                    array_list1.remove(position);
                                    alphaAdapter3.notifyItemRemoved(position);
                                }
                                alphaAdapter3.notifyDataSetChanged();
                            }
                        });

        recyclerView.addOnItemTouchListener(swipeTouchListener);


    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        //  Toast.makeText(getBaseContext(), tab.toString(), 5).show();
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        //      Toast.makeText(getBaseContext(), tab.toString(), 5).show();
        vp.setCurrentItem(tab.getPosition());
        if (tab.getPosition() == 2) {


            tab_2.setCustomView(null);
            tab_2.setCustomView(R.layout.tab_layout_2);

            tab_1.setCustomView(null);
            tab_1.setCustomView(R.layout.tab_layout_1);


            tab_3.setCustomView(null);
            tab_3.setCustomView(R.layout.tab_layout_33);


        } else if (tab.getPosition() == 1) {


            tab_2.setCustomView(null);
            tab_2.setCustomView(R.layout.tab_layout_22);

            tab_1.setCustomView(null);
            tab_1.setCustomView(R.layout.tab_layout_1);


            tab_3.setCustomView(null);
            tab_3.setCustomView(R.layout.tab_layout_3);


        } else if (tab.getPosition() == 0) {

            tab_1.setCustomView(null);
            tab_1.setCustomView(R.layout.tab_layout_11);


            if (tab_2 != null) {

                tab_2.setCustomView(null);
                tab_2.setCustomView(R.layout.tab_layout_2);
            }


            if (tab_3 != null) {

                tab_3.setCustomView(null);
                tab_3.setCustomView(R.layout.tab_layout_3);
            }


        }
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        //  Toast.makeText(getBaseContext(), tab.toString(), 5).show();

    }


    public interface OnItemTouchListener {

        // this will disallow the touch request for parent scroll on touch of child view


        /**
         * Callback invoked when the user Taps one of the RecyclerView items
         *
         * @param view     the CardView touched
         * @param position the index of the item touched in the RecyclerView
         */
        public void onCardViewTap(View view, int position);

        /**
         * Callback invoked when the Button1 of an item is touched
         *
         * @param view     the Button touched
         * @param position the index of the item touched in the RecyclerView
         */
        public void onButton1Click(View view, int position);

        /**
         * Callback invoked when the Button2 of an item is touched
         *
         * @param view     the Button touched
         * @param position the index of the item touched in the RecyclerView
         */
        public void onButton2Click(View view, int position);
    }

    public class CustomPagerAdapter extends PagerAdapter {

        private final Context mContext;
        private final Vector<View> pages;

        public CustomPagerAdapter(Context context, Vector<View> pages) {
            this.mContext = context;
            this.pages = pages;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            View page = pages.get(position);
            container.addView(page);


            return page;
        }

        @Override
        public int getCount() {
            return pages.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view.equals(object);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }


    }

    public class CardViewAdapter extends RecyclerView.Adapter<CardViewAdapter.ViewHolder> {
        ArrayList<HashMap<String, String>> d;
        Activity a;
        private List<String> cards;
        private OnItemTouchListener onItemTouchListener2;


        public CardViewAdapter(OnItemTouchListener onItemTouchListener, Activity a, ArrayList<HashMap<String, String>> d) {
            //  this.cards = cards;
            this.onItemTouchListener2 = onItemTouchListener;
            this.a = a;
            this.d = d;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view_layout, viewGroup, false);
            return new ViewHolder(v);
        }

        @Override
        public void onBindViewHolder(ViewHolder viewHolder, int i) {
            //  viewHolder.title.setText(cards.get(i));

            HashMap<String, String> item = d.get(i);
            viewHolder.title.setText(item.get("category"));
            imageLoader.displayImage(item.get("image"), viewHolder.im2);

        }

        @Override
        public int getItemCount() {
            //   return d == null ? 0 : d.size();
            return (null != d ? d.size() : 0);
            // return d.size();
        }

        public class ViewHolder extends RecyclerView.ViewHolder {

            MotionEvent motionEvent;
            private int mSlop;
            private int mMinFlingVelocity;
            private int mMaxFlingVelocity;
            private long mAnimationTime;
            // Fixed properties
            //   private RecyclerView mRecyclerView;
            private SwipeableRecyclerViewTouchListener.SwipeListener mSwipeListener;

            // Transient properties
            private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
            private int mDismissAnimationRefCount = 0;
            private float mAlpha;
            private float mDownX;
            private float mDownY;
            private boolean mSwiping;
            private int mSwipingSlop;
            private VelocityTracker mVelocityTracker;
            private int mDownPosition;
            private int mAnimatingPosition = ListView.INVALID_POSITION;
            private View mDownView;
            private boolean mPaused;
            private float mFinalDelta;
            ///
            private TextView title;
            private Button button1;
            private Button button2;
            private ImageView im2;

            public ViewHolder(View itemView) {
                super(itemView);
                title = (TextView) itemView.findViewById(R.id.card_view_title);

                im2 = (ImageView) itemView.findViewById(R.id.imageView);

            }
        }
    }


}

activity_main.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/relativelayout_1">


    <LinearLayout
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:layout_alignParentBottom="true"
        Android:layout_alignParentStart="true"
        Android:id="@+id/linearlayout_1"
        Android:orientation="vertical">

        <Android.support.v4.view.ViewPager
            Android:id="@+id/vp"
            Android:layout_width="match_parent"
            Android:layout_height="0dp"

            Android:layout_weight="1"
            />


    </LinearLayout>


</RelativeLayout>

sample2.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/re1"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:scrollbars="vertical">

</Android.support.v7.widget.RecyclerView>

</RelativeLayout>
19
jason

この問題を解決するために、ItemTouchHelperが提供するAndroidを使用して、RecyclerViewからアイテムを簡単にスワイプして削除しました。

以下の実装を参照してください。

MainActivity

ここにViewPagerの実装があり、その子はFragmentsです。

_package za.co.gadgetgirl.testcardpager;

import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.support.v4.app.FragmentManager;
import Android.support.v4.app.FragmentPagerAdapter;
import Android.support.v4.view.ViewPager;
import Android.support.v7.app.AppCompatActivity;

import Java.util.ArrayList;
import Java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);
    }

    private void setupViewPager(ViewPager viewPager) {
        Adapter adapter = new Adapter(getSupportFragmentManager());

        Frag1 frag1 = new Frag1();
        Frag2 frag2 = new Frag2();
        Frag3 frag3 = new Frag3();

        adapter.addFragment(frag1, "frag1");
        adapter.addFragment(frag2, "frag2");
        adapter.addFragment(frag3, "frag3");
        viewPager.setAdapter(adapter);
    }

    static class Adapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragments = new ArrayList<>();
        private final List<String> mFragmentTitles = new ArrayList<>();

        public Adapter(FragmentManager fm) {
            super(fm);
        }

        public void addFragment(Fragment fragment, String title) {
            mFragments.add(fragment);
            mFragmentTitles.add(title);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitles.get(position);
        }
    }
}
_

Frag1

このFragmentにはRecyclerViewが添付されたItemTouchHelperがあります。 ItemTouchHelperSimpleCallbackインターフェースで定義されているonSwiped(...)メソッドをリッスンし、このメソッドでスワイプされたアイテムを削除します。

_package za.co.gadgetgirl.testcardpager;

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.support.v7.widget.helper.ItemTouchHelper;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;

public class Frag1 extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.frag1, container, false);

        final RecyclerView rv = (RecyclerView) v.findViewById(R.id.rv);
        final LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        rv.setLayoutManager(llm);

        final RVAdapter rvAdapter = new RVAdapter(Person.initializeData());
        rv.setAdapter(rvAdapter);

        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                rvAdapter.removeItem(viewHolder.getAdapterPosition());
            }
        });

        itemTouchHelper.attachToRecyclerView(rv);

        return v;
    }

}
_

RVAdapter

_public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> {


    //...implementation...

    public void removeItem(int position) {
        persons.remove(position);
        notifyItemRemoved(position);
    }
}
_

ItemTouchHelperを使用するには、アプリのgradleファイルで定義されている_appcompat-v7:22.2.0_以上の依存関係が必要です。

1
Cindy

私はこれまでSwipeableRecyclerViewを使ったことがないので、あまり言えません。以前と同じ問題があります。フラグメントのベースコンテナ(onTouchLinearLayoutなど)のRelativeLayoutイベントを処理することで解決し、うまくいきます。このソリューションを試して、私たちに戻ってみませんか

0
Sun Maung Oo

あなたが説明しているユースケースでは、ViewPagerがスワイプアクションを取得するために使用したいクラスではないと思います。 CoordinatorLayoutSwipeDismissBehavior の組み合わせの方が適切だと思います。

編集:以下の私の解決策を参照してください:

レイアウトXML:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.v7.widget.CardView
            Android:id="@+id/cardView"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent">
    </Android.support.v7.widget.CardView>

</Android.support.design.widget.CoordinatorLayout>

アクティビティ:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CardView cardView = (CardView) findViewById(R.id.cardView);

        SwipeDismissBehavior<CardView> behavior = new SwipeDismissBehavior();
        behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
        behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
            @Override
            public void onDismiss(View view) {
                finish(); // close activity if desired 
            }

            @Override
            public void onDragStateChanged(int state) {

            }
        });

        ((CoordinatorLayout.LayoutParams) cardView.getLayoutParams()).setBehavior(behavior);
    }
}

また、 CoordinatorLayout の使用例をいくつか示します。

特に SwipeDismissBehavior を使用して多くの例を見つけることができませんでしたが、概念は上記のリンクに似ています。

または、同様の投稿の提案に従うこともできます。 Androidのスワイプレイアウトで閉じる 希望の結果を得ることができます。

お役に立てれば。

0
J. Beck