Android仿制滑动广告条

作者: 一个有故事的程序员 | 来源:发表于2018-05-29 18:31 被阅读10次

    开篇废话

    前些天看到知乎和网易在APP中加了一个滑动的广告,所以就仿做了一个,其实没什么技术含量,也没什么难度,滑动广告打GitHub地址,帮我点个Star。

    滑动广告条

    大概效果就是下图这样。

    滑动Banner

    思路

    自定义view,使滑动的时候,绘制改变。

    自定义view

    自定义一个ScrollBannerView,就是我们显示广告的view。

    public class ScrollBannerView  extends View {
    
        private Bitmap mBannerBitmap;
    
        private Rect rectSrc;
        private Rect rectDst;
    
        private int screenWidth;
        private int screenHeight;
    
        public ScrollBannerView(Context context) {
            super(context);
        }
    
        public ScrollBannerView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ScrollBannerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public void setBannerImageResource(@DrawableRes int resId) {
            mBannerBitmap = BitmapFactory.decodeResource(getResources(), resId);
    
            // 获取屏幕宽高
            WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics dm = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(dm);
            screenWidth = dm.widthPixels;
            screenHeight = dm.heightPixels;
    
            // 把图片修改为屏幕大小
            mBannerBitmap = scaleBitmap(mBannerBitmap, screenWidth, screenHeight);
        }
    
        public void notifyLayoutChange() {
            // 获取view当前位置
            int[] location = new int[2];
            getLocationOnScreen(location);
            int x = location[0];
            int y = location[1];
    
            // 定义需要截取图片的位置
            int showLeft = 0;
            int showTop = y;
            int showRight = mBannerBitmap.getWidth();
            int showBottom = y + getHeight();
    
            // 显示在屏幕上view的宽高
            int width = getWidth();
            int height = y + getHeight() > screenHeight ? screenHeight - y : getHeight();
    
            // 图片范围
            rectSrc = new Rect(showLeft, showTop, showRight, showBottom);
            // 绘制范围
            rectDst = new Rect(0, showTop < 0 ? -showTop : 0, width, height);
    
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            // 绘制
            if (mBannerBitmap != null && rectSrc != null && rectDst != null) {
                canvas.drawBitmap(mBannerBitmap, rectSrc, rectDst, null);
            }
        }
    
        private Bitmap scaleBitmap(Bitmap origin, int newWidth, int newHeight) {
            if (origin == null) {
                return null;
            }
            int height = origin.getHeight();
            int width = origin.getWidth();
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            Matrix matrix = new Matrix();
            matrix.postScale(scaleWidth, scaleHeight); // 使用后乘
            Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
            if (!origin.isRecycled()) {
                origin.recycle();
            }
            return newBM;
        }
    
    }
    

    布局中使用

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout 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.example.danlan.bannerimageviewdemo.MainActivity">
    
        <android.support.v4.widget.NestedScrollView
            android:id="@+id/scroll"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="@string/more_text"
                    />
    
                <com.cc.scrollbannerview.ScrollBannerView
                    android:id="@+id/banner"
                    android:layout_width="match_parent"
                    android:layout_height="180dp"
                    android:src="@drawable/banner" />
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="@string/more_text"
                    />
    
            </LinearLayout>
    
        </android.support.v4.widget.NestedScrollView>
    
    </android.support.constraint.ConstraintLayout>
    

    在Activity中使用

    public class MainActivity extends AppCompatActivity {
    
        private NestedScrollView mScroll;
        private ScrollBannerView mBanner;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            mScroll = (NestedScrollView) findViewById(R.id.scroll);
            mScroll.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
                @Override
                public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    if (mBanner != null){
                        mBanner.notifyLayoutChange();
                    }
                }
            });
            mBanner = (ScrollBannerView) findViewById(R.id.banner);
            mBanner.setBannerImageResource(R.drawable.banner);
        }
    
    }
    

    这里使用了NestedScrollView,NestedScrollView可以在滑动时回调,然后我们去对mBanner做相应的改变。

    写在后面

    这个Demo比较简单,没什么技术难点,如果还是有些不懂的,可以留言,我在文中可以做更多的解释。

    更多内容戳这里(整理好的各种文集)

    相关文章

      网友评论

      • 有点健忘:没用过这两个app,不过我感觉不应该是这种效果吧,那个图片应该有个移动的效果的吧,因为以前见过那种 列表样式的,每个列表背景都是一站图片,上下滑动的时候那些背景图也有移动的效果。
        一个有故事的程序员:知乎类似的创意广告有很多,我这个是其中一种。还有一种在滑动的时候,有微微上下抖动,也特别有感觉。你说的这种,知乎也用过。我只是写了其中一种,其它的,在方法一的基础上,稍作修改,比较容易实现。
      • 10TB的真爱:emmm 还有一个方法用Recyclerview 广告的item背景透明 其他item为白色
        一个有故事的程序员:我给补充了一下你说的方法,我当时是为了练习Drawable和自定义view写的。这些东西,不经常用,不熟练了。
        一个有故事的程序员:你也写个Demo,互相交流一下。

      本文标题:Android仿制滑动广告条

      本文链接:https://www.haomeiwen.com/subject/wthnjftx.html