自定义View以及View的属性的使用重点,xml中定义属性的值,包括Bitmap存为jpg样式可以模仿修改照片不喜欢的地方

程序的实现

主程序

package com.test.mypathview;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends Activity {
    private MyBitmip2 myView;
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myView = (MyBitmip2) findViewById(R.id.bitmap);
        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 获取cache通常会占用一定的内存,所以通常不需要的时候有必要对其进行清理,
                //通过destroyDrawingCache或setDrawingCacheEnabled(false)实现。
                //这里并未对其进行处理
                //一定要调用setDrawingCacheEnabled(false)方法来清空缓存区
                myView.setDrawingCacheEnabled(true);
                Bitmap bitmap = myView.getDrawingCache(true);
                //设置文件的路径,对文件进行存储
                File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis() + ".jpg");
                if (!file.exists()) {
                    try {
                        file.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    //100是控制图片的压缩比率
                    bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

继承View的类

package com.test.mypathview;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MyBitmip2 extends View {
    private int height;
    private int width;
    private Bitmap mBitmap;
    private Bitmap mBitmapPicture;
    private Canvas mBitmapCanvas;
    private Paint mPaintCircle;
    private Paint mPaintRec;
    private Path mPathPicture;

    public MyBitmip2(Context context,AttributeSet attrs) {
        super(context,attrs);
        mPaintCircle = new Paint();
        mPaintCircle.setColor(Color.RED);
        /** * 必须自定义属性 */
        //改变背景图片,根据样式中background的传入值
        final TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.myview);
        //得到BitmapDrawable的myview_background
        BitmapDrawable drawable=(BitmapDrawable) ta.getDrawable(R.styleable.myview_myview_background);
        if(drawable!=null){
            mBitmapPicture=drawable.getBitmap();
        }else{
            //当为空时传入默认图片
            mBitmapPicture=BitmapFactory.decodeResource(getResources(),R.drawable.a);
        }

        /** * 在红色图层上描绘的线的设置,重叠部分则变为透明 */
        mPaintRec = new Paint();
        mPaintRec.setColor(Color.YELLOW);
        //设置重叠则变为透明
        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
        mPaintRec.setXfermode(mode);
        // 设置画笔画出的是什么样式的线
        mPaintRec.setStrokeJoin(Paint.Join.ROUND);
        // 设置画笔起始点的形状
        mPaintRec.setStrokeCap(Paint.Cap.ROUND);
        // 设置画笔宽度
        int paintWidth=ta.getDimensionPixelOffset(R.styleable.myview_myview_paint_width,30);
        mPaintRec.setStrokeWidth(paintWidth);
        //设置画笔的样式
        mPaintRec.setStyle(Paint.Style.FILL_AND_STROKE);
        //设置画线的形式,具体参照http://www.cnblogs.com/tianzhijiexian/p/4297783.html
        mPaintRec.setPathEffect(new CornerPathEffect(90));
        //设置是否去除锯齿
        mPaintRec.setAntiAlias(true);

// //得到背景图片
// mBitmapPicture = BitmapFactory.decodeResource(getResources(),R.drawable.a);


        //设置记录在上面画线的路径
        mPathPicture = new Path();
    }

    public MyBitmip2(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);

        height = getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec));
        //首先设置怎个屏幕为画板,并定义了画板的颜色样式
        mBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
        mBitmapCanvas = new Canvas(mBitmap);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //mBitmapPicture既是背景图,也是要截取的图,第一个Rect是截取图的大小,第二个则是把这个截取图放在多大的画布上
        canvas.drawBitmap(mBitmapPicture,new Rect(0,0,mBitmapPicture.getWidth(),mBitmapPicture.getHeight()),width,height),null);
        // 注意画的顺序,这是进行蒙版的画制
        mBitmapCanvas.drawRect(0,mPaintCircle);
        //则是进行上面点触的重叠图层进行绘制
        mBitmapCanvas.drawPath(mPathPicture,mPaintRec);
        canvas.drawBitmap(mBitmap,null);
    }

    private float downx;
    private float downy;
    private float oldx;
    private float oldy;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downx = event.getX();
            downy = event.getY();
            //中间用path记录点触位置的变化
            mPathPicture.moveTo(downx,downy);
            invalidate();
            oldx = downx;
            oldy = downy;
            invalidate();
            return true;
        case MotionEvent.ACTION_MOVE:
            downx = event.getX();
            downy = event.getY();
            invalidate();
            mPathPicture.moveTo(oldx,oldy);
            //quadto是画贝塞尔曲线
            mPathPicture.quadTo((downx + oldx) / 2,(downy + oldy) / 2,downx,downy);
            invalidate();
            //保存此次的坐标,以便之后直线的绘制
            oldx = downx;
            oldy = downy;
            //通过返回true 结束本次事件
            return true;
        default:
            break;
        }
        return super.onTouchEvent(event);
    }

}

主布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:view="http://schemas.android.com/apk/res/com.test.mypathview" android:layout_width="match_parent" android:layout_height="match_parent" >
    <!-- 在上面导入自己的样式,跟自己的包名,并定义名字,然后根据名字使用自己定义的属性-->
    <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button"/>
    <!--在布局文件中使用自己定义的属性-->
    <com.test.mypathview.MyBitmip2  android:id="@+id/bitmap" android:layout_width="match_parent" android:layout_height="match_parent" view:myview_background="@drawable/c" view:myview_paint_width="100dp"/>

    <TextView  android:id="@+id/textview" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:gravity="center" android:text="A" android:textSize="100sp" />

</RelativeLayout>

自定义属性文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 这个名为样式名就是根据R.styleable.myview寻找的名字 -->
    <declare-styleable name="myview">
        <!-- 设置其中各个属性的名字,以及属性的限定-->
        <attr name="myview_background" format="reference" ></attr>
        <attr name="myview_paint_width" format="dimension|reference"></attr>
    </declare-styleable>
</resources>

参考

<?xml version="1.0" encoding="utf-8"?>  
<resources>  

    <attr name="rightPadding" format="dimension" />  

    <declare-styleable name="SlidingMenu">  
        <attr name="rightPadding" />  
    </declare-styleable>  

</resources>

另外注意

在本例中使用这个小编来使图片适应整个屏幕,但是我们也可以使用matrix来放大图片,使用时必须使用Matrix.reset()恢复正常,然后就可以放大图片了。

canvas.drawBitmap(mBitmapPicture,null);

效果图

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇