最终效果:

Android setSpan 背景 android背景颜色_android

(最终效果录屏后转成gif时色彩有些误差还在闪烁,直接在手机上运行是没有这种情况的。)

思路:获取轮播图当前图片的主题色并且设置给背景

首先简单写一个轮播图

因为会用到网络图片先申请权限

<uses-permission android:name="android.permission.INTERNET" /> <!-- 访问网络权限 -->

引入轮播图和图片显示依赖

implementation 'com.github.bumptech.glide:glide:4.9.0'
    implementation 'com.youth.banner:banner:2.0.10'

编写轮播布局

<?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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/ll_bg"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:orientation="vertical">
            <com.youth.banner.Banner
                android:id="@+id/banner"
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:layout_margin="15dp" />
    </LinearLayout>


</LinearLayout>

加载显示轮播图

private LinearLayout mLlBg;
    private Banner mBanner;
    private List<BannerBean> mBannerBeans;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        mLlBg = findViewById(R.id.ll_bg);
        mBanner = findViewById(R.id.banner);
        initBanner();
    }

    private void initBanner() {
        //模拟数据
        mBannerBeans = new ArrayList<>();
        mBannerBeans.add(new BannerBean(1, "http://p1.music.126.net/yG5m3OK4ZBBeOIkSftmjcQ==/109951165905030496.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(2, "http://p1.music.126.net/ETIySI2MCkINdRWDFK_QQQ==/109951165905559297.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(3, "http://p1.music.126.net/zzAHDSg9nWA90dJL0U6rRQ==/109951165906140657.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(4, "http://p1.music.126.net/Ly3Qh10IMv5_yjDwQTlxvA==/109951165905725276.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(5, "http://p1.music.126.net/bOg67Q_MhDgMK3xK9BRTPA==/109951165905708968.jpg?imageView&quality=89"));
        //自定义适配器
        MyBannerAdapter myBannerAdapter = new MyBannerAdapter(mBannerBeans, this);
        mBanner.setAdapter(myBannerAdapter)
                .isAutoLoop(true)//自动切换
                .setDelayTime(2000)//轮播时间
                .setBannerRound(10)//圆角
                .setIndicator(new RectangleIndicator(this));//设置指示器;

    }

class MyBannerAdapter extends BannerAdapter<BannerBean, MyBannerAdapter.BannerViewHolder> {
    private Context mContext;

    public MyBannerAdapter(List<BannerBean> data, Context context) {
        super(data);
        this.mContext = context;
    }

    @Override
    public BannerViewHolder onCreateHolder(ViewGroup parent, int viewType) {
        ImageView imageView = new ImageView(parent.getContext());
        //设置为match_parent 这个是viewpager2要求
        imageView.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        return new BannerViewHolder(imageView);
    }

    @Override
    public void onBindView(BannerViewHolder holder, BannerBean data, int position, int size) {
        Glide.with(mContext)
                .load(data.thumb)
                .centerCrop()
                .into(holder.imageView);
    }

    class BannerViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;
        public BannerViewHolder(@NonNull ImageView view) {
            super(view);
            this.imageView = view;
        }
    }
}

到这第一步测试的轮播图就显示完成了。

获取轮播图片的颜色并生成线性背景

为了获取颜色我们使用android的palette,它能获取图片中的多种颜色,在实际情况中根据需求使用特定颜色

  • vibrant(鲜艳色)
  • dark vibrant(鲜艳色中的暗色)
  • light vibrant(鲜艳色中的亮色)
  • muted(柔和色)
  • dark muted(柔和色中的暗色)
  • light muted(柔和色中的亮色)

使用palette首先加入依赖: 

implementation 'androidx.palette:palette:1.0.0'

因为palette需要图片为bitmap,所以首先通过glide把网络图片转为bitmap(子线程中操作)

//把网络图片转成bitmap
                        myBitmap = Glide.with(MainActivity3.this)
                                .asBitmap()
                                .load(banner.thumb)//图片链接
                                .submit(50, 50)
                                .get();

通过palette获取bitmap中颜色

Palette.from(myBitmap).generate(new Palette.PaletteAsyncListener() {
                            @Override
                            public void onGenerated(Palette palette) {
                                if (palette == null) return;
                                //不一定取得到某些特定的颜色,这里通过取多种颜色来避免取不到颜色的情况
                                if (palette.getDarkVibrantColor(Color.TRANSPARENT) != Color.TRANSPARENT) {
                                    //使用鲜艳色中的暗色和鲜艳色生成线性背景
                                    createLinearGradientBitmap(banner.id, palette.getDarkVibrantColor(Color.TRANSPARENT), palette.getVibrantColor(Color.TRANSPARENT));
                                } else if (palette.getDarkMutedColor(Color.TRANSPARENT) != Color.TRANSPARENT) {
                                    //使用柔和色中的暗色和柔和色生成线性背景
                                    createLinearGradientBitmap(banner.id, palette.getDarkMutedColor(Color.TRANSPARENT), palette.getMutedColor(Color.TRANSPARENT));
                                } else {
                                    //使用柔和色中的亮色和鲜艳色中的亮色生成线性背景
                                    createLinearGradientBitmap(banner.id, palette.getLightMutedColor(Color.TRANSPARENT), palette.getLightVibrantColor(Color.TRANSPARENT));
                                }
                            }
                        });

通过获取的两种颜色创建线性背景,为了以后轮播图播放图和背景对应,用map保存生成的bitmap

Bitmap bgBitmap = null;
    Canvas mCanvas = null;
    Paint mPaint = null;
    //创建线性渐变背景色
    private void createLinearGradientBitmap(int id, int color1, int color2) {
        try {
            //通过这三个基础色进行渐变
            int bgColors[] = new int[3];
            bgColors[0] = color1;
            bgColors[1] = color2;
            bgColors[2] = Color.WHITE;
            bgBitmap = Bitmap.createBitmap(mLlBg.getWidth(), mLlBg.getHeight(), Bitmap.Config.ARGB_4444);
            mCanvas = new Canvas();
            mPaint = new Paint();
            mCanvas.setBitmap(bgBitmap);
            mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            //纵向的线性渐变
            LinearGradient gradient = new LinearGradient(0, 0, 0, bgBitmap.getHeight(), bgColors, null, Shader.TileMode.CLAMP);
            mPaint.setShader(gradient);
            //绘制矩形
            RectF rectF = new RectF(0, 0, bgBitmap.getWidth(), bgBitmap.getHeight());
            mCanvas.drawRect(rectF, mPaint);
            mBgBitmaps.put(id, bgBitmap);
            bgBitmap = null;

        } catch (Exception e) {
        }
    }

到这我们已经把渐变背景根据id对应起来存储到了map中。

根据当前轮播显示的图片改变背景

首先监听banner的切换

//轮播图切换监听
        mBanner.addOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }
            @Override
            public void onPageSelected(int position) {
                BannerBean data = mBannerBeans.get(position);
                showBgBitmap(data.id);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

展示相应的背景

//根据当前轮播图id设置背景
    private void showBgBitmap(int id) {
        if (mBgBitmaps != null && mBgBitmaps.size() > 0) {
            BitmapDrawable bitmapDrawable = new BitmapDrawable(mBgBitmaps.get(id));
            mLlBg.setBackground(bitmapDrawable);
        }
    }

完整代码

public class MainActivity3 extends AppCompatActivity {
    private LinearLayout mLlBg;
    private Banner mBanner;
    private List<BannerBean> mBannerBeans;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        mLlBg = findViewById(R.id.ll_bg);
        mBanner = findViewById(R.id.banner);
        initBanner();
    }

    private void initBanner() {
        //模拟数据
        mBannerBeans = new ArrayList<>();
        mBannerBeans.add(new BannerBean(1, "http://p1.music.126.net/yG5m3OK4ZBBeOIkSftmjcQ==/109951165905030496.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(2, "http://p1.music.126.net/ETIySI2MCkINdRWDFK_QQQ==/109951165905559297.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(3, "http://p1.music.126.net/zzAHDSg9nWA90dJL0U6rRQ==/109951165906140657.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(4, "http://p1.music.126.net/Ly3Qh10IMv5_yjDwQTlxvA==/109951165905725276.jpg?imageView&quality=89"));
        mBannerBeans.add(new BannerBean(5, "http://p1.music.126.net/bOg67Q_MhDgMK3xK9BRTPA==/109951165905708968.jpg?imageView&quality=89"));
        //采集每个图片的颜色
        setBgBitmap(mBannerBeans);
        //自定义适配器
        MyBannerAdapter myBannerAdapter = new MyBannerAdapter(mBannerBeans, this);
        mBanner.setAdapter(myBannerAdapter)
                .isAutoLoop(true)//自动切换
                .setDelayTime(2000)//轮播时间
                .setBannerRound(10)//圆角
                .setIndicator(new RectangleIndicator(this));//设置指示器;
          //轮播图切换监听
        mBanner.addOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }
            @Override
            public void onPageSelected(int position) {
                BannerBean data = mBannerBeans.get(position);
                showBgBitmap(data.id);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
    }
    //根据当前轮播图id设置背景
    private void showBgBitmap(int id) {
        if (mBgBitmaps != null && mBgBitmaps.size() > 0) {
            BitmapDrawable bitmapDrawable = new BitmapDrawable(mBgBitmaps.get(id));
            mLlBg.setBackground(bitmapDrawable);
        }
    }

    //存放各个轮播图对应的背景颜色
    HashMap<Integer, Bitmap> mBgBitmaps;
    private void setBgBitmap(List<BannerBean> banners) {
        mBgBitmaps = new HashMap<>();
        //子线程中操作
        new Thread() {
            public void run() {
                Bitmap myBitmap;
                for (BannerBean banner : banners) {
                    try {
                        //把网络图片转成bitmap
                        myBitmap = Glide.with(MainActivity3.this)
                                .asBitmap()
                                .load(banner.thumb)
                                .submit(50, 50)
                                .get();
                        Palette.from(myBitmap).generate(new Palette.PaletteAsyncListener() {
                            @Override
                            public void onGenerated(Palette palette) {
                                if (palette == null) return;
                                //不一定取得到某些特定的颜色,这里通过取多种颜色来避免取不到颜色的情况
                                if (palette.getDarkVibrantColor(Color.TRANSPARENT) != Color.TRANSPARENT) {
                                    //使用鲜艳色中的暗色和鲜艳色生成线性背景
                                    createLinearGradientBitmap(banner.id, palette.getDarkVibrantColor(Color.TRANSPARENT), palette.getVibrantColor(Color.TRANSPARENT));
                                } else if (palette.getDarkMutedColor(Color.TRANSPARENT) != Color.TRANSPARENT) {
                                    //使用柔和色中的暗色和柔和色生成线性背景
                                    createLinearGradientBitmap(banner.id, palette.getDarkMutedColor(Color.TRANSPARENT), palette.getMutedColor(Color.TRANSPARENT));
                                } else {
                                    //使用柔和色中的亮色和鲜艳色中的亮色生成线性背景
                                    createLinearGradientBitmap(banner.id, palette.getLightMutedColor(Color.TRANSPARENT), palette.getLightVibrantColor(Color.TRANSPARENT));
                                }
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    Bitmap bgBitmap = null;
    Canvas mCanvas = null;
    Paint mPaint = null;
    //创建线性渐变背景色
    private void createLinearGradientBitmap(int id, int color1, int color2) {
        try {
            //通过这三个基础色进行渐变
            int bgColors[] = new int[3];
            bgColors[0] = color1;
            bgColors[1] = color2;
            bgColors[2] = Color.WHITE;
            bgBitmap = Bitmap.createBitmap(mLlBg.getWidth(), mLlBg.getHeight(), Bitmap.Config.ARGB_4444);
            mCanvas = new Canvas();
            mPaint = new Paint();
            mCanvas.setBitmap(bgBitmap);
            mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            //纵向的线性渐变
            LinearGradient gradient = new LinearGradient(0, 0, 0, bgBitmap.getHeight(), bgColors, null, Shader.TileMode.CLAMP);
            mPaint.setShader(gradient);
            //绘制矩形
            RectF rectF = new RectF(0, 0, bgBitmap.getWidth(), bgBitmap.getHeight());
            mCanvas.drawRect(rectF, mPaint);
            mBgBitmaps.put(id, bgBitmap);
            //首先显示第一个图片的背景
            if (1 == id)
                mLlBg.setBackground(new BitmapDrawable(bgBitmap));
            bgBitmap = null;

        } catch (Exception e) {
        }
    }

}

class MyBannerAdapter extends BannerAdapter<BannerBean, MyBannerAdapter.BannerViewHolder> {
    private Context mContext;

    public MyBannerAdapter(List<BannerBean> data, Context context) {
        super(data);
        this.mContext = context;
    }

    @Override
    public BannerViewHolder onCreateHolder(ViewGroup parent, int viewType) {
        ImageView imageView = new ImageView(parent.getContext());
        //设置为match_parent 这个是viewpager2要求
        imageView.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        return new BannerViewHolder(imageView);
    }

    @Override
    public void onBindView(BannerViewHolder holder, BannerBean data, int position, int size) {
        Glide.with(mContext)
                .load(data.thumb)
                .centerCrop()
                .into(holder.imageView);
    }

    class BannerViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;
        public BannerViewHolder(@NonNull ImageView view) {
            super(view);
            this.imageView = view;
        }
    }
}

总结

到这里功能已经全部实现了,轮播图的背景可以根据轮播图当前图片的改变而改变,为了美观你也可以获取到的不同颜色来生成线性背景看哪一个好看……。如果需求不是轮播图,只是根据单张图片来改变背景颜色或者主题颜色也可以修改下使用。