第一节 安卓自定义轮播图的制作

专栏目录

  1. 第一节 自定义轮播图的制作
  2. 第二节 底部导航栏菜单,炫酷菜单动画,背景变暗、按钮焦点获取
  3. 第三节 适配Android10的拍照、从相册获取代码,包括完整的权限申请和图片地址获取
  4. 第四节 百度定位、地图SDK,和风天气获取教程
  5. 第五节 微信朋友圈式九宫格添加图片展示(待更新)
  6. 第六节 第三方api获取淘宝数据,用RecyclerView进行商品展示、刷新和搜索(待更新)

引言

在安卓开发中,我们经常要在首页用到轮播图来展示商品或者传达app所要传达的理念。当然网上也有很多开源的第三方库来调用实现轮播图,不过要想自己制作一个与众不同的轮播图,就要理解轮播图的实现原理,从而自定义轮播图。下面我将带领大家学习一种轮播图的制作方法,有问题大家可以留言并讨论。

效果图

在这里插入图片描述

Java代码

public class MainActivity extends AppCompatActivity {
    private ViewPager mViewPaper;
    private List<ImageView> images;
    //下方指示点
    private List<View> dots;
    private int currentItem;
    //记录上一次点的位置
    private int oldPosition = 0;
    //存放图片的id
    private int[] imageIds = new int[]{R.drawable.pic1, R.drawable.pic2, R.drawable.pic3};
    //存放图片的标题,可以设为空
    private String[] titles = new String[]{"title1", "title2", "title3"};
    private TextView title;
    private ViewPagerAdapter adapter;
    //定时调度机制
    private ScheduledExecutorService scheduledExecutorService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setView();
    }
    //UI界面的更新
    private void setView(){
        mViewPaper = findViewById(R.id.viewpager);
        //显示的图片
        images = new ArrayList<ImageView>();
        for(int i = 0; i < imageIds.length; i++){
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(imageIds[i]);
            images.add(imageView);
        }
        //显示的小点
        dots = new ArrayList<View>();
        dots.add(findViewById(R.id.dot_0));
        dots.add(findViewById(R.id.dot_1));
        dots.add(findViewById(R.id.dot_2));

        title = findViewById(R.id.title);
        title.setText(titles[0]);

        adapter = new ViewPagerAdapter();
        mViewPaper.setAdapter(adapter);

        mViewPaper.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                title.setText(titles[position]);
                dots.get(position).setBackgroundResource(R.drawable.dot_yes);
                dots.get(oldPosition).setBackgroundResource(R.drawable.dot_no);
                oldPosition = position;
                currentItem = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }

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

            }
        });
    }

    /*定义的适配器*/
    public class ViewPagerAdapter extends PagerAdapter {
        //返回当前有效视图的个数。
        @Override
        public int getCount() {
            return images.size();
        }
        //判断instantiateItem函数所返回来的Key与一个页面视图是否是代表的同一个视图
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup view, int position, Object object) {
            view.removeView(images.get(position));
        }
        //创建指定位置的页面视图,也就是将一张图片放到容器中的指定位置
        @Override
        public Object instantiateItem(ViewGroup view, int position) {
            view.addView(images.get(position));
            return images.get(position);
        }

    }

    /**
     * 利用线程池定时执行动画轮播
     */
    @Override
    public void onStart() {
        super.onStart();
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        //每隔2s时间,固定执行轮播任务。
        scheduledExecutorService.scheduleWithFixedDelay(new ViewPageTask(), 2, 2, TimeUnit.SECONDS);
    }

    /**
     * 图片轮播任务,发送轮播消息
     */
    private class ViewPageTask implements Runnable{
        @Override
        public void run() {
            currentItem = (currentItem + 1) % imageIds.length;
            mHandler.sendEmptyMessage(0);   //发送轮播消息
        }
    }

    /**
     * 接收子线程传递过来的数据
     */
    private Handler mHandler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            //这里不是具体的数据,而是一个轮播信号,目的是切换下一张图片
            mViewPaper.setCurrentItem(currentItem);
        }
    };

    //当切换到其他界面时,关闭后台轮播
    @Override
    public void onStop() {
        super.onStop();
        if(scheduledExecutorService != null){
            scheduledExecutorService.shutdown();
            scheduledExecutorService = null;
        }
    }
}

XMl代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="250dp" >
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="230dip">
            <androidx.viewpager.widget.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="35dip"
                android:layout_gravity="bottom"
                android:background="#33000000"
                android:gravity="center"
                android:orientation="vertical">
                <TextView
                    android:id="@+id/title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text=""
                    android:textColor="@android:color/white" />
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="3dip"
                    android:orientation="horizontal">

                    <View
                        android:id="@+id/dot_0"
                        android:layout_width="5dip"
                        android:layout_height="5dip"
                        android:layout_marginLeft="2dip"
                        android:layout_marginRight="2dip"
                        android:background="@drawable/dot_yes" />

                    <View
                        android:id="@+id/dot_1"
                        android:layout_width="5dip"
                        android:layout_height="5dip"
                        android:layout_marginLeft="2dip"
                        android:layout_marginRight="2dip"
                        android:background="@drawable/dot_no" />

                    <View
                        android:id="@+id/dot_2"
                        android:layout_width="5dip"
                        android:layout_height="5dip"
                        android:layout_marginLeft="2dip"
                        android:layout_marginRight="2dip"
                        android:background="@drawable/dot_no" />
                </LinearLayout>
            </LinearLayout>
        </FrameLayout>

    </RelativeLayout>
</LinearLayout>

图片资源(3张轮播图和2张底部圆点)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注:你可以把圆点换成你想要的任何图片。

Fragment中代码修改

以上代码是在Activity中使用的,如果要在Fragment中使用需要进行一下修改。即在onCreateView中对xml视图进行绑定。

@Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myView = inflater.inflate(R.layout.activity_main, container, false);
        mViewPaper = myView.findViewById(R.id.viewpager);

        //显示的小点
        dots = new ArrayList<View>();
        dots.add(myView.findViewById(R.id.dot_0));
        dots.add(myView.findViewById(R.id.dot_1));
        dots.add(myView.findViewById(R.id.dot_2));
        dots.add(myView.findViewById(R.id.dot_3));
        dots.add(myView.findViewById(R.id.dot_4));

        title = myView.findViewById(R.id.title);
        return myView;
	}

有任何问题欢迎大家留言,整理制作不易,若有帮助,烦请您关注、点赞、收藏。

  • 13
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
Android自定义控件可以使用ViewPager和Handler实现: 1. 首先创建一个自定义的ViewPager类,并重写onTouchEvent()方法,实现手势滑动效果。 ``` public class MyViewPager extends ViewPager { private float startX; private float startY; private OnItemClickListener onItemClickListener; public MyViewPager(Context context) { super(context); } public MyViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: startX = ev.getX(); startY = ev.getY(); break; case MotionEvent.ACTION_UP: float endX = ev.getX(); float endY = ev.getY(); if (startX == endX && startY == endY) { if (onItemClickListener != null) { onItemClickListener.onItemClick(getCurrentItem()); } } break; } return super.onTouchEvent(ev); } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } public interface OnItemClickListener { void onItemClick(int position); } } ``` 2. 创建一个自定义的轮控件类,继承自LinearLayout,并在该类中初始化ViewPager和指示器,并设置自动轮。 ``` public class MyBanner extends LinearLayout { private Context mContext; private MyViewPager mViewPager; private LinearLayout mIndicatorLayout; private List<ImageView> mIndicatorViews; private List<String> mImageUrls; private int mCurrentItem = 0; private Handler mHandler = new Handler(); public MyBanner(Context context) { super(context); initView(context); } public MyBanner(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } private void initView(Context context) { mContext = context; View view = LayoutInflater.from(mContext).inflate(R.layout.my_banner_layout, this); mViewPager = (MyViewPager) view.findViewById(R.id.viewpager); mIndicatorLayout = (LinearLayout) view.findViewById(R.id.indicator_layout); } public void setImageUrls(List<String> imageUrls) { mImageUrls = imageUrls; initIndicator(); mViewPager.setAdapter(new MyBannerAdapter()); mViewPager.setCurrentItem(Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2 % mImageUrls.size())); startAutoScroll(); } private void initIndicator() { mIndicatorViews = new ArrayList<>(); for (int i = 0; i < mImageUrls.size(); i++) { ImageView indicatorView = new ImageView(mContext); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.rightMargin = 20; indicatorView.setLayoutParams(params); if (i == 0) { indicatorView.setImageResource(R.drawable.indicator_selected); } else { indicatorView.setImageResource(R.drawable.indicator_normal); } mIndicatorLayout.addView(indicatorView); mIndicatorViews.add(indicatorView); } } private void startAutoScroll() { mHandler.postDelayed(new Runnable() { @Override public void run() { mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1); mHandler.postDelayed(this, 2000); } }, 2000); } private class MyBannerAdapter extends PagerAdapter { @Override public int getCount() { return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public Object instantiateItem(ViewGroup container, final int position) { ImageView imageView = new ImageView(mContext); imageView.setScaleType(ImageView.ScaleType.FIT_XY); Glide.with(mContext).load(mImageUrls.get(position % mImageUrls.size())).into(imageView); container.addView(imageView); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "点击了第" + (position % mImageUrls.size() + 1) + "张片", Toast.LENGTH_SHORT).show(); } }); return imageView; } } } ``` 3. 在布局文件中使用自定义的轮控件。 ``` <com.example.myapplication.MyBanner android:id="@+id/banner" android:layout_width="match_parent" android:layout_height="200dp" /> ``` 4. 在代码中设置轮片地址。 ``` List<String> imageUrls = new ArrayList<>(); imageUrls.add("http://img2.imgtn.bdimg.com/it/u=202085641,1798154443&fm=27&gp=0.jpg"); imageUrls.add("http://img5.imgtn.bdimg.com/it/u=2746360890,4221331673&fm=27&gp=0.jpg"); imageUrls.add("http://img0.imgtn.bdimg.com/it/u=3054917406,3471798182&fm=27&gp=0.jpg"); mBanner.setImageUrls(imageUrls); ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特立独行の猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值