技术共享之手写广告条(ViewPager)

现在的app ,广告条一般都是必不可少的模块,可以说是软件的标配。有的用第三方的,也有的自己写,第三方的容易,节约开发周期。也有很多想自己写,来提升自己。下面我来给大家分享如何手写一个广告条。
先看效果——->
这里写图片描述

先讲一下原理 外部容器使用了RelativieLayout ,把圆点 和描述内容直接覆盖在viewpager 上,那个导航点其实很容易做的 ,使用xml 或者 让美工切图。本人使用xml 实现的,实现步骤 ,viewpager 实现图片加载 ,监听滑动的状态,其中 会出现一些bug 例如,按住图片还会动,直接 用 重写 image view 的 onTouchEvent 就行了。下面开始撸码

第一步 在drawable 中 新建xml 实现 导航点

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

其中的 gray_point.xml 和 blue_point.xml 分别用shape 做 的
gray_point.xml

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

blue_point.xml

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

第二步,就是绘制布局 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test.liang.viewpageradvertisement.MainActivity">


    <!--广告条-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200sp">
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
<!--圆点-->
        <LinearLayout
            android:id="@+id/ll_point"
            android:layout_width="match_parent"
            android:layout_height="50sp"
            android:orientation="horizontal"
            android:background="#44000000"
            android:layout_alignParentBottom="true"
            android:gravity="center"
            android:layout_marginBottom="40sp"
            >
        </LinearLayout>

<!--描述-->
        <TextView
            android:id="@+id/tv_Des"
            android:layout_width="match_parent"
            android:layout_height="40sp"
            android:orientation="horizontal"
            android:background="#44000000"
            android:layout_alignParentBottom="true"
            android:gravity="center"
            android:textColor="@color/colorAccent"
            android:textSize="18sp"
            />

    </RelativeLayout>

</LinearLayout>

这个布局也没什么难度,接下来就是具体实现了

第三步,写MainActivity.java

package com.test.liang.viewpageradvertisement;

import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
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 AdvertisementAdapter adapter;
    private  ImageView pointImage ;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {

            //设置 加载下一个
            int item = viewpager.getCurrentItem() + 1;
            viewpager.setCurrentItem(item);
            handler.sendEmptyMessageDelayed(0,4000) ;

        }
    };
    private ViewPager viewpager;
    private LinearLayout llPoint;
    private TextView llDes;
    private List<String> mTitles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewpager = (ViewPager) findViewById(R.id.viewpager);
        llPoint = (LinearLayout) findViewById(R.id.ll_point);  //点的容器
        llDes = (TextView) findViewById(R.id.tv_Des);      //描述

        initView();
        initListenner();
    }
    protected void initView() {
        // 准备数据

        List<Integer> imgId = new ArrayList<>();
        List<ImageView> imageViews = new ArrayList<>();
        mTitles = new ArrayList<>();
        imgId.add(R.drawable.mainschool);
        imgId.add(R.drawable.activity);
        imgId.add(R.drawable.water);
        imgId.add(R.drawable.eastlake);

        mTitles.add("学院风光");
        mTitles.add("校运动会");
        mTitles.add("校园一角");
        mTitles.add("美丽东湖");



        for (int i = 0; i < imgId.size(); i++) {
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setBackgroundResource(imgId.get(i));  //设置背景图
            pointImage = new ImageView(MainActivity.this);
            pointImage.setBackgroundResource(R.drawable.point);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.setMargins(8,8,8,8);
            pointImage.setLayoutParams(layoutParams);
            if(i == 0)
            {
                pointImage.setEnabled(true);
            }else
            {
                pointImage.setEnabled(false);
            }


            llPoint.addView(pointImage);  //相容其中添加 圆球


            imageViews.add(imageView);    //添加图片

        }


        adapter = new AdvertisementAdapter(null, imageViews,handler);
        viewpager.setAdapter(adapter);
        viewpager.setCurrentItem(Integer.MAX_VALUE / 2);
        llDes.setText(mTitles.get((Integer.MAX_VALUE / 2) % mTitles.size()));
        for (int i = 0 ; i <llPoint.getChildCount() ; i ++)
        {
            if(i ==  Integer.MAX_VALUE / 2 % llPoint.getChildCount())
            {
                llPoint.getChildAt(i).setEnabled(true);
            }
            else {
                llPoint.getChildAt(i).setEnabled(false);
            }
            handler.sendEmptyMessageDelayed(0,4000) ;

        }


    }

    protected void initListenner() {

        viewpager.addOnPageChangeListener(new 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) {
                //需求 : 变换圆点 的位置

                for (int i = 0 ; i < llPoint.getChildCount() ; i ++)
                {

                    if(i == position % llPoint.getChildCount())
                    {
                        llPoint.getChildAt(i).setEnabled(true);
                        llDes.setText(mTitles.get(i));
                    }
                    else
                    {
                        llPoint.getChildAt(i).setEnabled(false);
                    }

                }

            }
            /**
             *  当页面滑动状态改变的时候调用
             * @param state
             *  静止--》滑动
             *  滑动--> 静止
             *  静止--> 拖拽
             */


            @Override
            public void onPageScrollStateChanged(int state) {
                switch (state) {
                    case ViewPager.SCROLL_STATE_DRAGGING: //当拖动的时候回调
                        handler.removeCallbacksAndMessages(null);
                        break;
                    case ViewPager.SCROLL_STATE_IDLE:     //当空闲的时候调用
                        handler.removeCallbacksAndMessages(null);
                        handler.sendEmptyMessageDelayed(0, 4000);
                        break;
                    case ViewPager.SCROLL_STATE_SETTLING:  // 当拖拽的时候回调
                        handler.removeCallbacksAndMessages(null);
                        break;
                }

            }
        });
    }
}

其中用到了 适配器,在此就行建一个类

package com.test.liang.viewpageradvertisement;

import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.List;

/**
 * Created by 梁 on 2017/12/21.
 * 此类实现广告条的效果
 */

public class AdvertisementAdapter extends PagerAdapter {

 private    List<ImageView>imageViews ;
 private    List<String> mTitles ;
 private  Handler handler  ;
    public AdvertisementAdapter(List<String> mTitles, List<ImageView> imageViews, Handler handler) {
//        this.imageViews = imageViews ;
        this.mTitles = mTitles ;
        this.imageViews = imageViews ;
        this.handler = handler ;
    }

    /**
     *  相当于getVIew方法
     * @param container  就是viewpager 自身 容器
     * @param position   当前viewpager加载的位置
     * @return
     */

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int realPosition = position % imageViews.size();
        ImageView imageView = imageViews.get(realPosition);
        container.addView(imageView);

        //当图片按下的时候 取消 自动滑动
        imageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction())
                {
                    case  MotionEvent.ACTION_DOWN : //按下的时候调用
                        handler.removeCallbacksAndMessages(null);
                        break;
                        case  MotionEvent.ACTION_MOVE : //滑动的时候调用
                            handler.removeCallbacksAndMessages(null);
                        break;
                        case  MotionEvent.ACTION_UP : //手指拿开的时候调用
                            handler.sendEmptyMessageDelayed(0,4000);
                        break;
                }

                return true;
            }
        });
        Log.d("instantiateItem","container:" + container +"position:" + position);
        return imageView;
    }


    @Override
    public int getCount() {
        return Integer.MAX_VALUE;  //设为最大值
    }


    /**
     * 判断 view 和object 是不是 同一个实例
     * @param view     页面
     * @param object  instantiateItem()方法中返回来的 实例
     * @return
     */

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        Log.d("isViewFromObject","view:" + view +"objecct:" + object);
        return view == object;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
        Log.d("释放的位置","container" + container +"position:" + position +"objecct:" + object);
    }
}

源码已经上传至http://download.csdn.net/download/baidu_38477614/10167567 有需要的直接联系我 Q 1915528523 也可以留言 ,我发到你们的邮箱内。

猜你喜欢

转载自blog.csdn.net/baidu_38477614/article/details/78862901