Android图片轮播列表的实现

这个效果在交友app中比较常见,一般作为首页使用,顶部是一个自动轮播的ViewPager,下面放一个横向LinearLayout,最下面要放一个ListView,但是注意这三个部分都支持滑动,应该和固定在顶部的标题栏和底部的操作栏分开,也就是把ViewPager和LinearLayout以及ListView都放在父控件ScrollView里面

布局文件代码:





    





    

    

        

        

        

        
    

    



    

        

        

        

        
    

主窗口代码:

public class IndexActivity extends AppCompatActivity implements View.OnClickListener{

    private Context mContext;
    private List mImageList;
    private List mCandidateList;
    private ViewPagerAdapter mPagerAdapter;
    private CandidateListAdapter mListAdapter;

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            //每次将当前的位置加1,也就是向右滑动一次
            vp.setCurrentItem(vp.getCurrentItem() + 1);
            //递归无限循环调用
            handler.sendEmptyMessageDelayed(0x123, 2000);
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_index);
        ButterKnife.bind(this);

        initData();
        initView();
        intListener();
    }

    //初始化数据源,固定写法 1.实例化容器 2.实例化适配器 3.设置适配器
    private void initData() {
        mContext = this;
        mImageList = new ArrayList<>();
        mCandidateList = new ArrayList<>();
        mListAdapter = new CandidateListAdapter(mCandidateList);
        mPagerAdapter = new ViewPagerAdapter(mImageList);
        lvfsv.setAdapter(mListAdapter);
        vp.setAdapter(mPagerAdapter);

        getListData(10);
        getPagerData();

        //间隔2秒发送一次信息
        handler.sendEmptyMessageDelayed(0x123, 2000);
    }

    //生成ViewPager数据源
    private void getPagerData() {
        mImageList.add(R.drawable.bm1);
        mImageList.add(R.drawable.bm2);
        mImageList.add(R.drawable.bm3);
        mImageList.add(R.drawable.bm4);
        mImageList.add(R.drawable.bm5);
        mImageList.add(R.drawable.bm6);

        mPagerAdapter.notifyDataSetChanged();
        //初始的位置在正中间
        vp.setCurrentItem(mPagerAdapter.getCount() / 2);
    }

    //生成ListView数据源
    private void getListData(int num) {
        for (int i = 0; i < num; i++) {
            Candidate candidate = new Candidate();
            candidate.setName("姓名:尼尔斯·亨利克·戴维·玻尔");
            candidate.setInfo("职业:学者,物理学家,足球运动员");
            candidate.setTrait("成就:哥本哈根学派的创始人,1922年获得诺贝尔物理学奖");
            mCandidateList.add(candidate);
        }

        mListAdapter.notifyDataSetChanged();
    }

    private void initView() {
        tvTitleMiddle.setText("轮播列表");
        //手动设置ScrollView的位置
        scrollView.smoothScrollTo(0, 0);
    }

    //初始化监听
    private void intListener() {
        mPagerAdapter.setmCallback((v, position) -> {
            Toast.makeText(mContext, "position: " + position, Toast.LENGTH_SHORT).show();
        });

        lvfsv.setOnItemClickListener((parent, view, position, id) -> {
            Toast.makeText(mContext, "position: " + position, Toast.LENGTH_SHORT).show();
        });

        for (int i = 0; i < 4; i++) {
            ivs.getChildAt(i).setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){
            case R.id.iv1:
            case R.id.iv2:
            case R.id.iv3:
            case R.id.iv4:
                Toast.makeText(mContext, "此处跳转", Toast.LENGTH_SHORT).show();
        }
    }
}

ListView需要覆盖onMeasure方法,代码如下:

public class ListViewForScrollView extends ListView {
    public ListViewForScrollView(Context context) {
        super(context);
    }
    public ListViewForScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public ListViewForScrollView(Context context, AttributeSet attrs,
        int defStyle) {
        super(context, attrs, defStyle);
    }
    @Override
    /**
     * 重写该方法,达到使ListView适应ScrollView的效果
     */
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
        MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

ViewPager适配器代码:

public class ViewPagerAdapter extends PagerAdapter implements View.OnClickListener {

    //图片的资源id列表
    private List mList;
    private Callback mCallback;

    public ViewPagerAdapter(List mList) {
        this.mList = mList;
    }

    public void setmCallback(Callback mCallback) {
        this.mCallback = mCallback;
    }

    public interface Callback {
        void onClick(View v, int position);
    }

    @Override
    //将适配器中的数据设为无穷大
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    //固定写法,不覆盖会报错
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }

    @Override
    //固定写法
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        LayoutInflater inflater = LayoutInflater.from(container.getContext());
        ImageView imageView = (ImageView) inflater.inflate(R.layout.item_image_pager, null);

        //将position转换成余数
        int realPosition = position % mList.size();
        imageView.setImageResource(mList.get(realPosition));
        imageView.setOnClickListener(this);
        //tag放跳转需要的数据
        imageView.setTag(realPosition);
        //将实例加入父控件
        container.addView(imageView);
        return imageView;
    }

    @Override
    //使用接口将position回传
    public void onClick(View v) {
        mCallback.onClick(v, (int) v.getTag());
    }
}

大功告成,实现效果如下:

你可能感兴趣的:(Java)