設置圖片輪流滑動播放的效果——學習筆記

上一篇已經說道了怎麼通過請求網絡獲得的數據來更新ListView的UI,這次是在上一次的基礎上給ListView頂部加上一個輪播圖的效果,同時完善更多的佈局。
首先是關於ListView的設置,上次的ListView只在一個頁面中,現在可以先創建多頁ListView,然後把這些頁面放入一個ViewPager中,然後結合TabLayout,這樣就做成一個基本的左右滑動切換瀏覽新聞列表的效果。

上次Okhttp3的使用方式不完整,先說一下用okhttp去請求網絡。
首先把以下方法放入一個HttpUtil類中,方便調用:

    //使用okhttp3
    public static void sendOkHttpRequest(String url, okhttp3.Callback callback){
        OkHttpClient client = new OkHttpClient();
        okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .build();
        client.newCall(request).enqueue(callback);
    }

然後使用okhttp請求網絡的時候,只需要:

private void getDataByOkhttp(){
        HttpUtil.sendOkHttpRequest(url, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.e("使用okhttp失敗~~~");
            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) throws IOException {
                LogUtil.e("使用okhttp成功~~~當前線程是——" + Thread.currentThread().getName());
                final String data = response.body().string();
                //json數據類
                final NewsTopBeanAuto bean = HttpUtil.parsedJsonWithGson(data);
                String title = bean.getResult().getResult().getChannel();
                MainActivity mainActivity = (MainActivity) context;
                mainActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        processData(data);
                    }
                });
                LogUtil.e("數據解析成功,標題是——" + title );
            }
        });
    }

這是okhttp最基本的使用方式了,用這個結合Gson去獲取新聞的列表,把Gson解析數據方法也放在HttpUtil中:


    //使用Gson解析數據
    public static NewsTopBeanAuto parsedJsonWithGson(String json) {
//        Gson gson = new Gson();
//        NewsTopBean bean = gson.fromJson(json, NewsTopBean.class);
        return new Gson().fromJson(json, NewsTopBeanAuto.class);
    }

也是最基本的用法。
然後在ListView所在的頁面去請求數據,在上一篇中可以看到ListView的效果,每一行數據之間有兩條分隔線,這時候只需要添加一個android:divider=”@null”屬性即可,下面是ListView的佈局listview_detailpager.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ListView
        android:id="@+id/listview"
        android:divider="@null"
        android:cacheColorHint="@android:color/transparent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

這條屬性添加後ListView列表是這樣的:
這裏寫圖片描述

ListView佈局就是這樣,然後需要給它添加頂部輪播圖片的佈局,我在一個app中(應該有人看得出來是啥子app)找了一個基本上差不多的佈局效果,就是下面這樣:
這裏寫圖片描述
佈局裏面有圖片,文字,輪播時候切換的小原點。其實整個佈局還算簡單,小圓點是放在一個水平的LinearLayout中的,然後文字和這個LinearLayout可以放在一個相對佈局中,然後就是所有輪播的圖片放在一個ViewPager中,這個ViewPager和上面的相對佈局又放在一個相對佈局裏面,下面就是具體的佈局——top_news.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="200dp">

    <android.support.v4.view.ViewPager
        android:id="@+id/top_news_viewpager"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

    <RelativeLayout
        android:padding="5dp"
        android:background="#44000000"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/top_news_title"
            android:text="敲代碼的日常"
            android:layout_marginLeft="8dp"
            android:layout_centerVertical="true"
            android:textColor="@android:color/white"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <LinearLayout
            android:id="@+id/top_point_group"
            android:orientation="horizontal"
            android:layout_marginRight="8dp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </RelativeLayout>

</RelativeLayout>

這個佈局創建完成後,只需要通過ListView的addHeaderView方法,即可把這個輪播圖以頭佈局的方式添加到ListView上面。
差不多是這樣一個效果:
這裏寫圖片描述

現在當然是沒有圖片的,這個時候可以在輪播圖所在ViewPager適配器中,去加載圖片,使用Glide結合Okhttp去加載圖片,首先添加依賴:

compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:25.3.1'

然後在適配器的初始化視圖方法instantiateItem裏面使用Glide:

            ImageView imageView = new ImageView(context);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            Glide.with(context)
                    .load(listBeen.get(position).pic) //加載網絡圖片的地址
                    .error(R.drawable.huaji1)  //沒網時候加載這個
                    .into(imageView);
            container.addView(imageView);
            return imageView;

大概效果是這樣:
這裏寫圖片描述

這就是一個頁面的佈局,接下來先不去完善輪播圖的佈局,先把多個這樣的頁面放在ViewPager中結合TabLayout去顯示,把這些頁面顯示在一個NewsPager中去,下面是NewsPager的佈局newsdetail_pager.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <android.support.design.widget.TabLayout
            android:id="@+id/news_tablayout"
            android:layout_width="0dp"
            style="@style/MyCustomTabLayout"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"/>

        <ImageButton
            android:id="@+id/ib_tab_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@android:color/transparent"
            android:padding="5dp"
            android:src="@drawable/news_cate_arr"/>

    </LinearLayout>


    <android.support.v4.view.ViewPager
        android:id="@+id/newsdetail_viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

</LinearLayout>

很明顯,要把之前的頁面全部添加的上面的ViewPager中去,下面是集合了ListView和輪播圖頁面NewsDetailPager.class的代碼:

public class NewsDetailPager {
    private final Context context;
    private final String url;
    private ListView listView; //新聞列表
    public View rootView;
    private TextView top_news_title; // 頂部輪播圖標題
    private LinearLayout top_point_group; //頂部輪播圖滑動的小點
    private ViewPager top_news_viewpager; //頂部輪播圖的圖片

    public NewsDetailPager(Context context, String url) {
        this.context = context;
        this.url = url;
        rootView = initView();
    }

    public View initView() {
        View view = View.inflate(context, R.layout.listview_detailpager, null);
        listView = (ListView) view.findViewById(R.id.listview);

        View topNewsView = View.inflate(context, R.layout.top_news, null);
        top_news_viewpager = (ViewPager) topNewsView.findViewById(R.id.top_news_viewpager);
        top_news_title = (TextView) topNewsView.findViewById(R.id.top_news_title);
        top_point_group = (LinearLayout) topNewsView.findViewById(R.id.top_point_group);

        //把頂部輪播圖部分視圖,以頭的方式添加ListView中
        listView.addHeaderView(topNewsView);

        return view;
    }

    public void initData() throws JSONException {
        LogUtil.e("頁面數據被初始化——");
        String saveJson = CacheUtils.getString(context, url);
        if (!TextUtils.isEmpty(saveJson)){
            processData(saveJson);
        }
        getDataByOkhttp();
    }

    public void getDateByVolley(){
        RequestQueue queue = Volley.newRequestQueue(context);
        queue.add(getDataFromNetByVolley());
    }

    private void processData(String json) {
        final NewsTopBeanAuto bean = HttpUtil.parsedJsonWithGson(json);

        String title = bean.getResult().getResult().getChannel();
        List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen = bean.getResult().getResult().getList();
        LogUtil.e("解析Json數據成功----title2----:" + title);
        listView.setAdapter(new MyListViewAdapter(listBeen));
        top_news_viewpager.setAdapter(new MyTopViewPagerAdapter(listBeen));
    }


    private void getDataByOkhttp(){
        HttpUtil.sendOkHttpRequest(url, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.e("使用okhttp失敗~~~");
            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) throws IOException {
                LogUtil.e("使用okhttp成功~~~當前線程是——" + Thread.currentThread().getName());
                final String data = response.body().string();
                final NewsTopBeanAuto bean = HttpUtil.parsedJsonWithGson(data);
                String title = bean.getResult().getResult().getChannel();
                MainActivity mainActivity = (MainActivity) context;
                mainActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        processData(data);
                    }
                });
                LogUtil.e("數據解析成功,標題是——" + title );
            }
        });
    }



    //ListView的適配器
    private class MyListViewAdapter extends BaseAdapter {
        List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen;


        public MyListViewAdapter(List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen) {
            this.listBeen = listBeen;
        }

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

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null){
                convertView = View.inflate(context, R.layout.listview_detail, null);
                viewHolder = new ViewHolder();
                viewHolder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
                viewHolder.tv_time = (TextView) convertView.findViewById(R.id.tv_time);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            String data1 = listBeen.get(position).getTitle();
            String data2 = listBeen.get(position).getTime();
            viewHolder.tv_title.setText(data1);
            viewHolder.tv_time.setText(data2);
            LogUtil.e("內容是——" + data1 + data2);
            return convertView;
        }
    }

    public class ViewHolder {
        TextView tv_title;
        TextView tv_time;
    }

    private class MyTopViewPagerAdapter extends PagerAdapter {
        List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen;
        public MyTopViewPagerAdapter(List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen) {
            this.listBeen = listBeen;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imageView = new ImageView(context);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            Glide.with(context)
                    .load(listBeen.get(position).pic) //加載網絡圖片的地址
                    .error(R.drawable.huaji1)  //沒網時候加載這個
                    .into(imageView);
            container.addView(imageView);
            return imageView;
        }

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

        @Override
        public int getCount() {
            return 3;
        }

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

這之後就是NewsPager.class的代碼:

public class NewsPager extends  BasePager{

    private ArrayList<NewsDetailPager> newsDetailPagers;
    private ViewPager viewPager;
    private TabLayout tabLayout;
    private ImageButton ib_tab_next;

    public NewsPager(Context context) {
        super(context);
    }

    public View initThisView() {
        base_content_fl.removeAllViews();
        View view = View.inflate(context, R.layout.newsdetail_pager, null);
        viewPager = (ViewPager)view.findViewById(R.id.newsdetail_viewpager);
        tabLayout = (TabLayout) view.findViewById(R.id.news_tablayout);
        base_content_fl.addView(view);
        ib_tab_next = (ImageButton) view.findViewById(R.id.ib_tab_next);
        ib_tab_next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
            }
        });

        return base_content_fl;
    }

    @Override
    public void initData() {
        super.initData();
        LogUtil.e("新聞頁面數據被初始化——");
        initThisView();
        title_text.setText("新聞");
        LogUtil.e("當前主線程是——" + Thread.currentThread().getName());

        getNewsPagers();

    }


    public void getNewsPagers(){
        newsDetailPagers = new ArrayList<>();
        for (int i = 0 ; i < Constants.all_urls.length; i++){
            newsDetailPagers.add(new NewsDetailPager(context, Constants.all_urls[i]));
        }
        viewPager.setAdapter(new MyViewAdapter());
        tabLayout.setupWithViewPager(viewPager);
        viewPager.addOnPageChangeListener(new MyOnPageChangeListener());
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    }


    private class MyViewAdapter extends PagerAdapter {
        @Override
        public CharSequence getPageTitle(int position) {
            if(!TextUtils.isEmpty( CacheUtils.getString(context, Constants.all_urls[position]))){
                String json = CacheUtils.getString(context, Constants.all_urls[position]);
                NewsTopBeanAuto beanAuto = HttpUtil.parsedJsonWithGson(json);
                String title = beanAuto.getResult().getResult().getChannel();
                return title;
            } else {
                return Constants.all_titles[position];
            }
        }

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

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            NewsDetailPager newsDetailPager = newsDetailPagers.get(position);
            View rootView = null;
            try {
                rootView = newsDetailPager.rootView;
                newsDetailPager.initData();
                container.addView(rootView);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return rootView;
        }

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

    private class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (position == 0){
                //slidingMenu可以全屏滑動
                isEnableSlidingMenu(SlidingMenu.TOUCHMODE_FULLSCREEN);
            } else {
                //slidingMenu不可以滑動
                isEnableSlidingMenu(SlidingMenu.TOUCHMODE_NONE);
            }

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

    //根據傳入的參數設置SlidingMenu能否滑動的方法
    private void isEnableSlidingMenu(int touchMode) {
        MainActivity mainActivity = (MainActivity) context;
        mainActivity.getSlidingMenu().setTouchModeAbove(touchMode);
    }
}

其中,將TabLayout和ViewPager綁定在一起使用方法 tabLayout.setupWithViewPager(viewPager);
然後需要給ViewPager添加一個頁面監聽,設置了當不處於第一頁新聞的時候,取消掉SlidingMenu的滑動效果,這樣就消去了一個衝突。效果就是下面這個樣子的:

這裏寫圖片描述

不過這個時候,還有一些東西沒有設置完,比如小圓點還沒有設置,而且還有一個問題就是在第一個頁面的時候,右滑圖片會直接出現SlidingMenu的左側菜單。

首先,先設置滑動圖片對應的小圓點,其實之前的文章中,設置導航頁面的時候已經寫過如何設置小圓點了,上次是通過Shape屬性設置的點,這次可以直接使用圖片,效果是差不多的,步驟就是在上面的LinearLayout佈局中創建ImageView,然後添加進去:

//設置移動的小紅點
    private void addPoint() {
        top_point_group.removeAllViews();//由於processData要執行兩次,所以要添加一個移除紅點的方法,否則紅點的數量會是原來的兩倍
        for (int i = 0; i< 4; i++){
            ImageView imageView = new ImageView(context);
            imageView.setBackgroundResource(R.drawable.topnews_point_selector);//設置背景選擇器
            //設置點的大小
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(DensityUtils.dip2px(context, 5), DensityUtils.dip2px(context, 5));
            //默認第一個點爲紅色
            if (i == 0){
                imageView.setEnabled(true);
            } else {
                imageView.setEnabled(false);
                params.leftMargin = DensityUtils.dip2px(context, 8);
            }
            imageView.setLayoutParams(params);
            top_point_group.addView(imageView);
        }
    }

小圓點的佈局topnews_point_selector.xml是:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:drawable="@drawable/dot_normal"/>
    <item android:state_enabled="true" android:drawable="@drawable/dot_focus"/>

</selector>

上面是使用的兩張很小的圖片設置的,效果就是下面這樣:
這裏寫圖片描述

不過這時候紅點還是不能動的,這時候就需要監聽頂部輪播圖片的ViewPager的頁面,然後去更改紅點的位置,在此之前需要先設置一個prePosition = 0,表示點的默認位置,然後用以下方法去設置紅點:

top_news_viewpager.addOnPageChangeListener(new MyTopViewOnPageChangeListener(listBeen));//監聽頂部輪播圖片的滑動,然後改變紅點的位置

top_news_title.setText(listBeen.get(prePosition).getTitle());//設置默認第一個點的標題

下面是頁面的監聽:

private class MyTopViewOnPageChangeListener implements ViewPager.OnPageChangeListener {
        List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen;
        public MyTopViewOnPageChangeListener(List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen) {
            this.listBeen = listBeen;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            //設置圖片對應的標題
            top_news_title.setText(listBeen.get(position).getTitle());
            //將之前的點變爲白色
            top_point_group.getChildAt(prePosition).setEnabled(false);
            //當前點設爲紅色
            top_point_group.getChildAt(position).setEnabled(true);
            //把之前點的位置設置爲現在點的位置
            prePosition = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

然後看一下效果:
這裏寫圖片描述
這時候有一個bug,第一頁有時候會出現兩個紅點,比如下面這樣:
這裏寫圖片描述
其實這個問題很好解決,只需要在請求聯網的時候,把之前的prePosition設置爲0,就不會出現該bug了。

接着給下面的新聞列表也加上圖片,只要在listview_detail佈局中添加一個ImageView然後把文字列表所在的LinearLayout放在它的右邊或者左邊即可,然後在ListView的適配器裏面加載圖片和文字就行。下面是更改的佈局部分:

<ImageView
        android:id="@+id/iv_icon"
        android:layout_alignParentRight="true"
        android:scaleType="centerInside"
        android:layout_marginLeft="8dp"
        android:layout_centerVertical="true"
        android:src="@drawable/huaji1"
        android:layout_width="90dp"
        android:layout_height="90dp"/>

        <LinearLayout android:layout_centerVertical="true"
                      android:layout_alignParentLeft="true"
                      android:layout_marginLeft="5dp"
                      android:layout_toLeftOf="@+id/iv_icon"
                      android:orientation="vertical"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content">

            <TextView
                android:id="@+id/tv_title"
                android:text="爲什麼這麼難找bug呢"
                android:lines="2"
                android:textSize="16sp"
                android:textColor="@android:color/black"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

            <TextView
                android:layout_marginTop="8dp"
                android:id="@+id/tv_time"
                android:text="2017-10-14"
                android:textSize="14sp"
                android:textColor="#44000000"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </LinearLayout>

然後是更改後的效果:
這裏寫圖片描述

下面來說一下爲什麼在【頭條】頁面,右滑圖片會直接把SlidingMenu的左側菜單滑出來。

其實這就是滑動衝突的後果。在這裏,SlidingMenu作爲一個頂層的佈局,把我們的滑動事件給攔截了,也就是說滑動事件無法傳到頂部圖片所在的ViewPager中去,其實這個問題也好解決。

我們只需要重寫一個類繼承ViewPager,然後重寫它的dispatchTouchEvent()方法,在這個方法裏面去阻止父佈局攔截滑動事件即可,和前幾篇裏面使用RadioButton處理方法差不多。
寫一個HorizontalScrollViewPager.class繼承ViewPager:

public class HorizontalScrollViewPager extends ViewPager {
    public HorizontalScrollViewPager(Context context) {
        super(context);
    }

    public HorizontalScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        getParent().requestDisallowInterceptTouchEvent(true);//把事件都傳給當前控件
        return super.dispatchTouchEvent(ev);
    }
}

然後把之前聲明頂部輪播圖片的ViewPager替換成HorizontalScrollViewPager,同時把佈局裏面輪播圖所在的ViewPager也替換掉即可。

private HorizontalScrollViewPager top_news_viewpager; //頂部輪播圖的圖片
top_news_viewpager = (HorizontalScrollViewPager) topNewsView.findViewById(R.id.top_news_viewpager);

<com.example.administrator.simpleapp.pager.HorizontalScrollViewPager
        android:id="@+id/top_news_viewpager"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

然後看一下效果
這裏寫圖片描述

這時候滑動圖片就不會再調出左側菜單了,不過之前滑動圖片是可以切換新聞頁面的,但是現在卻不可以了,所以還可以完善一下。只需要設置,在圖片滑到第一個和最後一個的時候,把上面的

getParent().requestDisallowInterceptTouchEvent(true)屬性換成false就ok了,但是需要注意的一點是,在第一個【頭條】頁面,如果也是這樣設置的話,那在滑倒最後一張圖片的時候右滑,就又會調出左側菜單了,所以這時候不僅僅要判斷圖片是否是最後一個,還需要判斷滑動的方向。

下面就是修改後的代碼:

    private float startX; //起始的X座標
    private float startY; //起始的Y座標

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:   //手指按下的時候
                getParent().requestDisallowInterceptTouchEvent(true);//把事件都傳給當前控件
                startX = ev.getX(); //記錄起始的X座標
                startY = ev.getY();//記錄起始的Y座標
                break;
            case MotionEvent.ACTION_MOVE:  //手指移動的時候
                float endX = ev.getX(); //當前位置的X座標
                float endY = ev.getY(); //當前位置的Y座標
                //計算偏移量,然後根據在X軸、Y軸上誰的偏移量更大以及爲正數或負數,從而確定是水平的左右滑還是豎直的上下滑
                float distanceX = endX - startX;
                float distanceY = endY - startY;
                if (Math.abs(distanceX) > Math.abs(distanceY)){
                    //水平方向滑動
                    //當滑動到ViewPager的第0個頁面,並且是從左到右滑動
                    if (getCurrentItem() == 0 && distanceX > 0){
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }
                    //當滑動到ViewPager的最後一個頁面,並且是從右到左滑動
                    else if ((getCurrentItem() == (getAdapter().getCount() - 1)) && distanceX < 0){
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }
                    //其他
                    else{
                        getParent().requestDisallowInterceptTouchEvent(true);
                    }
                } else {
                    //豎直方向滑動
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

然後是修改後的效果
這裏寫圖片描述

然後,是如何讓圖片實現自動輪流播放的效果,可以通過Handler去實現:

    private InternalHandler internalHandler;
    class InternalHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //切換ViewPager的下一個頁面
            int item = (top_news_viewpager.getCurrentItem() + 1) % 4;//取餘
            top_news_viewpager.setCurrentItem(item);
            internalHandler.postDelayed(new MyRunnable(), 4000);
        }
    }
    class MyRunnable implements Runnable{
        @Override
        public void run() {
            internalHandler.sendEmptyMessage(0);
        }
    }

然後在processData()中添加:

        //是把消息隊列所有的消息和回調移除
        internalHandler.removeCallbacksAndMessages(null);
        internalHandler.postDelayed(new MyRunnable(), 4000);

不過如果這時候圖片是一直在循環,無法停止的,如果想通過手指按住圖片,不讓圖片滑動,就需要對圖片的觸摸事件監聽,於是在頂部輪播圖的ViewPager中對imageView進行監聽:

imageView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            LogUtils.e("按下");
                            //是把消息隊列所有的消息和回調移除
                            internalHandler.removeCallbacksAndMessages(null);
                            break;
                        case MotionEvent.ACTION_UP:
                            LogUtils.e("離開");
                            //是把消息隊列所有的消息和回調移除
                            internalHandler.removeCallbacksAndMessages(null);
                            internalHandler.postDelayed(new MyRunnable(), 4000);
                            break;
//                        case MotionEvent.ACTION_CANCEL:
//                            LogUtils.e("取消");
//                            //是把消息隊列所有的消息和回調移除
//                            internalHandler.removeCallbacksAndMessages(null);
//                            internalHandler.postDelayed(new MyRunnable(), 4000);
//                            break;
                        default:
                    }
                    return true;
                }
            });

然後爲了更加完善上面的效果,還可以在監聽圖片滑動的適配器中,對onPageScrollStateChanged進行補充:

private boolean isDragging = false;
        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_DRAGGING){ //拖拽狀態
                isDragging = true;
                //拖拽的時候要移除消息
                internalHandler.removeCallbacksAndMessages(null);
            } else if (state == ViewPager.SCROLL_STATE_SETTLING && isDragging){ //慣性狀態
                //發消息
                isDragging = false;
                internalHandler.removeCallbacksAndMessages(null);
                internalHandler.postDelayed(new MyRunnable(), 4000);
            } else if (state == ViewPager.SCROLL_STATE_IDLE && isDragging){//禁止狀態
                isDragging = false;
                internalHandler.removeCallbacksAndMessages(null);
                internalHandler.postDelayed(new MyRunnable(), 4000);
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章