在viewpager中图片滑动展示时图片与文字对应不上?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在viewpager中图片滑动展示时图片与文字对应不上?相关的知识,希望对你有一定的参考价值。

参考技术A 通常来说ViewPager可以和Fragment结合起来用,每次ViewPager滑动,也就是展示一个新的Fragment。Fragment里面就是我们需要展现的内容。而这滑动的动画就交给ViewPager来实现。所以第一步我们需要设置好Fragment的内容,新建一个布局文件,这里只需要展示一张图即可,当然可以根据自己的需要进行改变:

复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ImageView
android:id="@+id/iv_main_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/main_image"
android:scaleType="fitXY" />

</RelativeLayout>
复制代码

2. 然后建立Fragment类。

复制代码
import android.support.v4.app.Fragment;
......

public class PictureSlideFragment extends Fragment

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

View v = inflater.inflate(R.layout.fragment_picture_slide, container, false);

return v;



复制代码
3. 在Activity布局文件的合适位置加入ViewPager控件。

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

4. 在Activity中得到这个ViewPager并且为其设置Adapter:

复制代码
private ViewPager mPager;

@Override
protected void onCreate(Bundle savedInstanceState)
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mPager = (ViewPager) findViewById(R.id.pager);
  mPagerAdapter = new PictureSlidePagerAdapter(getSupportFragmentManager());
  mPager.setAdapter(mPagerAdapter);

复制代码

5. 这个Adapter继承自FragmentStatePagerAdapter,其中getCount()返回的值是一共需要显示的内容数,是个常数:

复制代码
private class PictureSlidePagerAdapter extends FragmentStatePagerAdapter

public PictureSlidePagerAdapter(FragmentManager fm)
super(fm);
// TODO Auto-generated constructor stub


@Override
public Fragment getItem(int arg0)
// TODO Auto-generated method stub
return new PictureSlideFragment();


@Override
public int getCount()
// TODO Auto-generated method stub
return NUM_PIC;


复制代码

6. 到目前为止所有的内容都和官方的教程一致。如果你在Fragment中的那个ImageView通过android:src属性设置图片,会实现数张静态图片滑动的效果。这离我们的目标还有一些区别:

(1)图片需要能够动态改变,而不是固定的内容;

(2)每张图片需要有点击的响应;

(3)一般情况下需要实现循环滚动,即滑到最后一张图时继续滑动会回到第一张图;

(4)图片要能够自动滚动;

(5)图片下方需要有显示第几张图的指示(小圆点)。

7. 接下来我们朝着目标继续努力。首先是图片的变化。观察上述Adapter的实现方法,可以发现getItem()方法每次返回的都是一个Fragment的实例,需要显示多少个Fragment这个方法就会执行多少遍。但我们发现每次创建新的Fragment都没有区别,直接new一个了事,因此我们需要改写这个创建新Fragment实例的方法,以实现每次新建的Fragment实例都不一样。在我们的Fragment类中补充如下内容:

复制代码
private int mIndex;

public static PictureSlideFragment newInstance(int index)
PictureSlideFragment f = new PictureSlideFragment();

Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);

return f;


@Override
public void onCreate(Bundle savedInstanceState)
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mIndex = getArguments() != null ? getArguments().getInt("index") : 1;


复制代码
这个叫做newInstance的方法主要功能也是创建一个Fragment实例,和直接new的区别是传递进来一个index参数,这个参数在onCreate()方法中被获得。然后我们将Adapter的getItem()改写为如下:

@Override
public Fragment getItem(int arg0)
// TODO Auto-generated method stub
return PictureSlideFragment.newInstance(arg0);

每次getItem都将Item的序号传递到新建的Fragment,然后再Fragment中根据需要设定不同的内容。真正实现的时候,可以在Fragment中加入从网络获取图片的操作。

8. 图片的点击响应。这个比较简单,在Fragment中获得ImageView控件,然后设置onClick监听器即可。就不给出代码了。

9. 图片的循环滚动。一般的ViewPager不能实现内容的循环滚动,即第一张向左滑或者最后一张向右滑都会到顶,显示到顶的效果。如果要从ViewPager自身入手加入这功能需要对这个控件进行改写,比较麻烦,这里我从stackoverflow上找到了一种比较聪明的办法。

  要实现几张图的循环滚动,其实只需要满足视觉效果就可以了。比如有三张图A,B,C,要实现A->B->C->A->B......以及C->B->A->C->B...这样的循环,实际上可以这样实现:

  提供5张图,分别是C' A B C A',其中C'和C,A'和A完全相同,当滑到C'时,自动切换到C,当滑到A'时,自动切换到A,并且这个切换过程没有动画,于是,使用者体验出来的感觉就是A B C三张图在循环滚动了。

  于是我们为ViewPager添加setOnPageChangeListener方法:

复制代码
mPager.setOnPageChangeListener(new OnPageChangeListener()

@Override
public void onPageSelected(int arg0)
// TODO Auto-generated method stub



@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
// TODO Auto-generated method stub



@Override
public void onPageScrollStateChanged(int state)
// 当到第一张时切换到倒数第二张,当到最后一张时切换到第二张
if (state == ViewPager.SCROLL_STATE_IDLE)
int curr = mPager.getCurrentItem();
int lastReal = mPager.getAdapter().getCount() - 2;
if (curr == 0)
mPager.setCurrentItem(lastReal, false);
else if (curr > lastReal)
mPager.setCurrentItem(1, false);



);
复制代码
覆写的onPageScrollStateChanged方法在滑动内容改变时调用,在其中实现C'和C,A'和A的切换。

10. 图片的自动滚动,这里我使用了timer启动线程来实现,定时器线程每隔5秒发送消息,UI线程捕获消息并调用ViewPager.setCurrentItem(currentItem+1, true)方法,滚动到下一张图片。代码就不赘述了。这里有个体验细节,就是当使用者用手指滑动时,定时器需要取消,防止自动滑动和手指滑动发生冲突。这个我在Fragment的ImageView的onTouchListener中实现:

复制代码
mMainImage.setOnTouchListener(new OnTouchListener()

@Override
public boolean onTouch(View v, MotionEvent event)
if (event.getAction() == MotionEvent.ACTION_DOWN)
((MainActivity)getActivity()).getTimer().cancel();
else if (event.getAction() == MotionEvent.ACTION_CANCEL)
((MainActivity)getActivity()).startSwitchImage();


return false;

);
复制代码

11. 图片序号的指示,也就是图片下方的几个小圆点,这个实现比较简单,首先在Activity的布局文件中添加几个图片,因为这几个小圆点本身不能随ViewPager移动,因此不能放在Fragment布局中。切换内容也就是切换显示不同颜色小圆点的位置,这个方法同样可以在onPageScrollStateChanged方法中调用。注意一些细节,因为之前为了实现循环滚动而多用了两个Fragment,而显示的小圆点数量不能增加,因此需要调整好对应的序号。代码也不再赘述了。

要是 还不明白 你来群里说吧 这里太麻烦了 给你解释怎么弄 look at my n a m e.本回答被提问者采纳
参考技术B 没描述清楚,完全没明白你想问什么。

viewpager实现广告滑动及文字滑动和下方 点的选中状态改变

效果如图:

技术分享

首先说下方的这几个点,这个点不是图片效果,而是Android自带的shape画的椭圆,使椭圆的宽高一样,就变成原型,然后设置颜色即可。

这2个点的代码如下:

    红色点的代码

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <size android:width="8dp" android:height="8dp"/>
    <solid android:color="#ff00"/>
</shape>

    灰色点的代码

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <size android:width="8dp" android:height="8dp"/>
    <solid android:color="#44000000"/>
</shape>


整体思路:

    1、要展示viewpager,就要先把图片获取,图片是放在drawable-hdpi里的5张图片。

    2、把图片放到一个list里,这个类似listview

    3、利用viewpager的适配器,展示图片

    4、在图片的适配器里根据位置加载每个图片资源,同时把图片下方的文字和选中的点显示

    5、同时在适配器里要销毁已经隐藏的图片占用的资源


    6、截止上一步,已经可以滑动图片了,但是图片滑动时,文字和点没有跟着变化,此时需要利用viewpage人的滑动监听,来处理文字变化和点的变化

    7、viewpager有一个

viewpager.addOnPageChangeListener(new MyOnPageChangeListener());

        监听,就new一个内部类,在内部类里通过图片滑动时的回调方法来实现。具体代码如下


MainActivity.java

package com.yuanlp.viewpager;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    private ViewPager viewpager;
    private TextView tv_title;
    private LinearLayout ll_point_group;

    private List<ImageView> imageviews;  //存放imageview的集合,以便后期放入pageadapter中

    //图片资源ID
    private final int[] imageIDs={
            R.drawable.a,
            R.drawable.b,
            R.drawable.c,
            R.drawable.d,
            R.drawable.e
    };

    //图片标题集合
    private final String[] imageDescriptions={
            "硅谷拔河比赛",
            "凝聚你我,放飞梦想",
            "抱歉,满座了",
            "七月热浪滔天",
            "加油努力学习"
    };


    //上一次点位高亮显示的位置
    private int prePosition=0;


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

        viewpager= (ViewPager) findViewById(R.id.viewpager);
        tv_title= (TextView) findViewById(R.id.tv_title);
        ll_point_group= (LinearLayout) findViewById(R.id.ll_point_group);

        imageviews=new ArrayList<ImageView>();
        MyPagerAdapter pagerAdapter=new MyPagerAdapter();
        for (int i=0;i<imageIDs.length;i++){
            //在这里把image一个一个new出来
            ImageView imageView=new ImageView(this);

            //这里引用图片设置为背景而不是src,是因为src可能会导致填充不完全
            imageView.setBackgroundResource(imageIDs[i]);

            //添加到集合
            imageviews.add(imageView);


            //添加点
            ImageView point=new ImageView(this);
            point.setBackgroundResource(R.drawable.selectors);
            LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(8,8);  //2个参数是宽和高
            if (i==0){
                point.setEnabled(true); //默认第0个显示红色选中
            }else{
                point.setEnabled(false); //其他为灰色
                params.leftMargin=8;    //设置和左边的为8个像素的间距
            }


            point.setLayoutParams(params);
            //添加到线性布局里
            ll_point_group.addView(point);

        }
        viewpager.setAdapter(pagerAdapter);

        //设置viewpage页面滑动的监听
        viewpager.addOnPageChangeListener(new MyOnPageChangeListener());

        //设置默认文本时第0个文本内容
        tv_title.setText(imageDescriptions[prePosition]);
    }

    /**
     * 页面滑动监听类
     */
    class MyOnPageChangeListener implements ViewPager.OnPageChangeListener{

        /**
         * 页面滚动时,回调该方法
         * @param position  当前的页面位置
         * @param positionOffset  滑动了页面的百分之多少
         * @param positionOffsetPixels  //屏幕上滑动了多少个像素
         */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        /**
         * 当某个页面被选中了的时候回调,即焦点图片
         * @param position  焦点图片的位置
         */
        @Override
        public void onPageSelected(int position) {
            //设置文本变化
            tv_title.setText(imageDescriptions[position]);

            //把上一个高亮的为灰色,把当前的设置为红色
            ll_point_group.getChildAt(prePosition).setEnabled(false);

            ll_point_group.getChildAt(position).setEnabled(true);
            prePosition=position;

        }

        /**
         * 滑动的过程中回调,状态的变化
         * 静止到滑动,滑动到静止,静止到拖拽
         * @param state
         */
        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }
    class MyPagerAdapter extends PagerAdapter{

        @Override
        /**
         * 得导图片总数
         */
        public int getCount() {
            return imageviews.size();
        }

        /**
         * 相当于getview方法,
         * @param container  本质上是viewpage人自身
         * @param position   当前实例化页面的位置
         * @return
         */
        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            ImageView imageView = imageviews.get(position);

            Log.e(TAG, "instantiateItem: 当前的位置"+position+"--------"+imageView);
            container.addView(imageView);  //添加到viewpager中
            return imageView;
        }


        /**
         * 比较view和object是否是同一个实例
         * @param view  页面
         * @param object 是上面的方法instantiateItem返回的结果
         * @return
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
         return view==object;

        }


        /**
         * 释放资源
         * @param container  是viewpager
         * @param position    要释放的位置
         * @param object       要释放的页面
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {

            container.removeView((View) object);
            Log.e(TAG, "destroyItem: 释放资源的位置"+position+"-------object");
        }
    }
}


本文出自 “YuanGuShi” 博客,请务必保留此出处http://cm0425.blog.51cto.com/10819451/1944598

以上是关于在viewpager中图片滑动展示时图片与文字对应不上?的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序获取轮播图当前图片下标滑动展示对应的位数点击位数展示对应图片

使用ViewPager实现图片轮播

viewpage 循环滑动播放图片

Android 滑动切换(首页展示,图片新闻自动切换,循环切换,自动和手动)

Android仿IOS ViewPager滑动进度条

android ViewPager实现 跑马灯切换图片+多种切换动画