Android图形处理-Drawabble

Android图形处理-Drawabble

Drawable

drawable是一个抽象类,本质就是图形和动画。

两种访问模式

  1. 通过@deawable/name在xml中引用
  2. 通过.drawable.name在java代码中使用

第二种使用方式的本质就是一个int

子类

sp161107_144448

主要的子类有:LayerDrawavle、ShapeDrawable、NinePathDrawable、StateListDrawable、ClipDrawable、AnimationDrawable。

LayerDrawavle

就是层的Drawable,新增的item会盖住原来的item所代表的图像,对应xml的标签是layer-list,

android:drawable表示对应的drawable就是图形或者动画

android:top|bottom|left|right表示图形在组件的位置

自定义SeekBar

switch201610311618

两个关键属性:

android:progressDrawable指定背景
android:thumb指定滑块

其中progressDrawable要指定两个Android官方的属性,分别制定划过的Drawable和没有划过的Drawable:

SeekBar的背景

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/background"/>
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/progress"/>

</layer-list>

@android:id/background官方指定的没有滑动的背景

@android:id/progress已经划过的颜色

SeekBar的代码

    <SeekBar android:layout_width="match_parent" 
             android:layout_height="wrap_content"
             android:progressDrawable="@drawable/layer" 
             android:thumb="@drawable/thumb"/>

主要是滑块的属性:android:thumb

ShapeDrawable

在xml中对应的shape属性

实例

sp161107_152406

代码

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <!--size表示这个shape的大小-->
    <size android:width="100dp" android:height="10dp"/>
    <!--solid表示这个形状怎么填充,其中只有一个color属性-->
    <solid android:color="@color/colorAccent"/>
    <!--stroke边框-->
    <stroke android:width="1dp" android:color="@color/colorPrimary"/>
    <!--gradient颜色渐变,默认的type是linear-->
    <gradient android:centerColor="@color/colorAccent"
              android:endColor="@color/colorPrimaryDark"
              android:startColor="@color/colorPrimary"
              android:type="linear"/>
    <!--padding图形的内边距-->
    <padding android:bottom="4dp"/>
    <!--corners处理图形的边角-->
    <corners android:radius="3dp"/>    
</shape>

StateListDrawable

对应xml中的selector

TextView自定义颜色

sp161107_153345

当EditText获得焦点的时候,字体颜色发生变化

代码

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_focused="true"/>
    <item android:color="@color/colorPrimary" android:state_focused="false"/>
</selector>

就是颜色和状态的结合

EditText的实现:

<EditText android:layout_width="match_parent"                       android:layout_height="wrap_content"
    android:text="你好"
    android:textColor="@drawable/color"/>

就是textColor属性指定Drawable

ClipDrawable

在xml中对应的clip标签

bug说明

sp161107_155143

在使用图片的时候一定要注意格式,出现这个错误就是图片的格式异常,在win直接改后缀名图片正常显示,但是在Andorid不能正常显示

出现错误的图片根本不能编译,无论图片是否正在使用

不断展开的画卷

switch2016110711hfhhs18

这就是不断的改变ClipDrawable的剪切位置来实现

ClipDrawable的实现
<clip xmlns:android="http://schemas.android.com/apk/res/android"
      android:clipOrientation="horizontal"
      android:drawable="@drawable/good"
      android:gravity="center">
</clip>

android:clipOrientation裁剪的方向

android:drawable裁剪的图片

android:gravity对其的方向

不断改变裁剪的Level
//  把ImageView的src抽取成一个Drawable
    private Drawable mDrawable;

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
//                不断改变level
                mDrawable.setLevel(mDrawable.getLevel() + 100);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
//        initAnim();
    }

    private void init() {
        ImageView imageView = (ImageView) findViewById(R.id.iv);
        mDrawable = imageView.getDrawable();
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 0;
                mHandler.sendMessage(message);
                if (mDrawable.getLevel() >= 10000) {
                    cancel();
                }
            }
//            设置周期是100毫秒
        }, 0, 100);
    }

注意可以实现周期的类Timer

Bitmap和BitmapDrawable

BItmapDrawable内部封装的就是一个Bitmap,也可以从Drawable中拿到Bitmap

一个Bitmap就是一张位图,而BitmapDrawable就是它的封装类,封装方法:

BitmapDrawable(Resources res, Bitmap bitmap) 

第一个参数就是: getApplicationContext().getResources()

可以调用BitmapDrawable中的getBitmap,反过来也可以:

Bitmap getBitmap ()

public class BitmapDrawable extends Drawable

还有一个重要的类就是BitmapFractory负责产生Bitmap:

sp161024_163637

就是几乎可以从各种资源加载并且装换成Bitmap

回收

BItmap加载显示大量耗费资源所以及时判断是否回收,BItmap有isRecycled和recycled两个方法分别判断是否回收和主动回收:

简单案例

就是两个button然后在assets目录中查找并且显示图片,借鉴自疯狂android:

  • 获取assets中的资源,并且存储在数组中
    private void init() {
        mAssetManager = getAssets();
        try {
            mList = mAssetManager.list("");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 添加事件监听
    @OnClick({R.id.button2, R.id.button})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button2:
  • 实现具体的逻辑

这里的思路很好玩,主要是应该用一个指针来指明哪个是正在显示的图片,然后在最开始就应该判断是否越界,这时候重点来了,通过文件名的后缀可以得到资源的类型(while),注意条件是反的,而且还应该判断是否越界:

                if (currentPicture >= mList.length) {
                    currentPicture = 0;
                }
                while (!mList[currentPicture].endsWith(".jpg")) {
                    currentPicture++;
                    if (currentPicture >= mList.length) {
                        currentPicture = 0;
                    }
                }

ImageView可以得到它的Dradable

BitmapDrawable drawable = (BitmapDrawable) mImageView.getDrawable();

AssetsManager打开资源:

mAssetManager.open(mList[currentPicture++]))
全部代码
    @BindView(R.id.button2)
    Button mButton2;
    @BindView(R.id.button)
    Button mButton;
    @BindView(R.id.imageView)
    ImageView mImageView;
    private String[] mList;
    private AssetManager mAssetManager;
    private int currentPicture = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        init();
    }

    private void init() {
        mAssetManager = getAssets();
        try {
            mList = mAssetManager.list("");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnClick({R.id.button2, R.id.button})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button2:
                if (currentPicture >= mList.length) {
                    currentPicture = 0;
                }
                while (!mList[currentPicture].endsWith(".jpg")) {
                    currentPicture++;
                  //注意这里要第二次判断是否越界的问题
                    if (currentPicture >= mList.length) {
                        currentPicture = 0;
                    }
                }
                BitmapDrawable drawable = (BitmapDrawable) mImageView.getDrawable();
                if (drawable != null && !drawable.getBitmap().isRecycled()) {
                    drawable.getBitmap().recycle();
                }

                try {
                    mImageView.setImageBitmap(BitmapFactory.decodeStream(mAssetManager.open(mList[currentPicture++])));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("---------------");

                break;
            case R.id.button:
                System.out.println("-------111111111111--------");
                break;
        }
    }

转载自:Android图形处理-Drawabble

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值