Bitmap的一个示例,一个类似于电脑上绘画板的一个程序

这里写图片描述

可以在上面随便画,还可以撤销。

MainActivity 类

public class MainActivity extends AppCompatActivity implements View.OnClickListener, ColorView.OnColorSelectListener, SeekBar.OnSeekBarChangeListener {

    DrawView drawView;
    ImageView ivMenu;

    boolean isStart;
    boolean isReform;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivMenu = (ImageView) findViewById(R.id.iv_menu);
        drawView = (DrawView) findViewById(R.id.drawview);
        ivMenu.setOnClickListener(this);
        drawView.setOnDrawStateChangedListener(new DrawView.OnDrawStateChangedListener() {
            @Override
            public void startDraw() {
                isStart = true;
                //只要又绘制了一条
                isReform = false;
            }

            @Override
            public void clearDraw() {
                isStart = false;
            }

            @Override
            public void reform(boolean b) {
                isReform = b;
            }
        });
    }

    PopupWindow popupWindow;

    @Override
    public void onClick(View v) {

        //PopupWindow
        //1.布局
        View layout = View.inflate(this, R.layout.popup_layout, null);
        TextView tvColor = (TextView) layout.findViewById(R.id.pop_tv_color);
        TextView tvWidth = (TextView) layout.findViewById(R.id.pop_tv_width);
        TextView tvClear = (TextView) layout.findViewById(R.id.pop_tv_clear);
        TextView tvCa = (TextView) layout.findViewById(R.id.pop_tv_ca);
        TextView tvRepeal = (TextView) layout.findViewById(R.id.pop_tv_repeal);
        TextView tvReform = (TextView) layout.findViewById(pop_tv_reform);
        TextView tvSave = (TextView) layout.findViewById(R.id.pop_tv_save);
        tvRepeal.setEnabled(isStart);
        tvReform.setEnabled(isReform);
        tvSave.setEnabled(isStart);

        tvCa.setOnClickListener(popwindowClick);
        tvColor.setOnClickListener(popwindowClick);
        tvWidth.setOnClickListener(popwindowClick);
        tvClear.setOnClickListener(popwindowClick);
        tvRepeal.setOnClickListener(popwindowClick);
        tvReform.setOnClickListener(popwindowClick);
        tvSave.setOnClickListener(popwindowClick);

        popupWindow = new PopupWindow(layout);
        //2. 宽高getResources().getDisplayMetrics().widthPixels / 3
        popupWindow.setWidth(getResources().getDisplayMetrics().widthPixels / 3);
        popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
        //3. 焦点
        popupWindow.setFocusable(true);
        //4. 触摸到外部的时候,是否关闭他
        popupWindow.setOutsideTouchable(true);
        //5. 如果要执行上面一句, 1.设置上下文 2.给一个空背景
        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        //显示
        popupWindow.showAsDropDown(ivMenu, 0, 20);
    }

    //pop点击事件
    private View.OnClickListener popwindowClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.pop_tv_color:
                    //getBaseContext;
//                    ColorDialog dialog = new ColorDialog(MainActivity.this);
//                    dialog.show();
                    SelectColorDialog dialog = new SelectColorDialog(MainActivity.this, MainActivity.this);
                    dialog.show();
                    break;
                case R.id.pop_tv_width:
                    WidthDialog dialog2 = new WidthDialog(MainActivity.this, MainActivity.this);
                    dialog2.show();
                    break;
                case R.id.pop_tv_clear:
                    drawView.clear();
                    break;
                case R.id.pop_tv_ca:
                    drawView.ca();
                    break;
                case R.id.pop_tv_repeal:
                    drawView.repeal();
                    break;
                case R.id.pop_tv_reform:
                    drawView.reform();
                    break;
                case R.id.pop_tv_save:
                    drawView.saveBitmap(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.png");
                    break;

            }
            //关闭pop
            popupWindow.dismiss();
        }
    };

    @Override
    public void onColorSelect(int color) {
        //选择了颜色
        drawView.setColor(color);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (fromUser) {
            drawView.setWidth(progress + 1);
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}

ColorDialog 类

public class ColorDialog extends Dialog {


    List<Integer> colors = new ArrayList<>();

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTitle("颜色选择");
        super.onCreate(savedInstanceState);
        GridView gv = new GridView(getContext());
        gv.setNumColumns(20); //255*255*255
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 16; j++) {
                for (int k = 0; k < 16; k++) {
                    colors.add(Color.rgb(i * i, j * j, k * k));
                }
            }
        }
        gv.setHorizontalSpacing(10);
        gv.setVerticalSpacing(10);
        gv.setGravity(Gravity.CENTER);
        gv.setAdapter(adapter);
        setContentView(gv);
    }


    private BaseAdapter adapter = new BaseAdapter() {
        @Override
        public int getCount() {
            return colors.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null)
                convertView = new View(getContext());
            GridView.LayoutParams params = new GridView.LayoutParams(10, 10);
            convertView.setLayoutParams(params);
            convertView.setBackgroundColor(colors.get(position));
            return convertView;
        }
    };

}

ColorView 类

public class ColorView extends View {

    //需要一张图片
    Bitmap bitmap;
    // int[] colors;

    public ColorView(Context context) {
        super(context);
        init();
    }

    public ColorView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public void init() {
        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.sepan);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.e("TAG", bitmap.getWidth() + "  " + bitmap.getHeight());
        super.onMeasure(MeasureSpec.makeMeasureSpec(bitmap.getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(bitmap.getHeight(), MeasureSpec.AT_MOST));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap, 0, 0, null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        Log.e("TAG", x + "   " + y);
        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
            int color = bitmap.getPixel((int) x, (int) y);
            setBackgroundColor(color);
            if (onColorSelectListener != null) {
                onColorSelectListener.onColorSelect(color);
            }
        }
        return true;
    }

    //回调
    public interface OnColorSelectListener {
        void onColorSelect(int color);
    }

    OnColorSelectListener onColorSelectListener;

    public void setOnColorSelectListener(OnColorSelectListener onColorSelectListener) {
        this.onColorSelectListener = onColorSelectListener;
    }
}

DrawView 类

public class DrawView extends View {

    Paint paint = new Paint();

    int backgroundColor = Color.WHITE;

    Path path;

    //绘制到一张图片上
    Bitmap cacheBitmap;
    Canvas cacheCanvas;

    boolean isCa = false;

    Paint caPaint = new Paint();

    public DrawView(Context context) {
        super(context);
        init();
    }

    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint.setDither(true);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        path = new Path();
        caPaint.setColor(backgroundColor);
        caPaint.setStrokeWidth(20);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //第一次测量的时候 没有高宽
        if (getWidth() != 0 && getHeight() != 0)
            initBitmap();
    }

    public void initBitmap() {
        cacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.RGB_565);
        //使用他绘制的 你看不到,绘制到了图片里面
        cacheCanvas = new Canvas(cacheBitmap);
        cacheCanvas.drawColor(backgroundColor);
    }

    //canvas是指屏幕的
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //清屏
        canvas.drawColor(backgroundColor);
        //绘制以前的线条
        canvas.drawBitmap(cacheBitmap, 0, 0, paint);
        if (isCa)
            canvas.drawPath(path, caPaint);
        else
            canvas.drawPath(path, paint);
    }


    //调整颜色
    public void setColor(int color) {
        paint.setColor(color);
    }

    public void setWidth(int width) {
        paint.setStrokeWidth(width);
    }

    //清除
    public void clear() {
        cacheBitmap.recycle();
        initBitmap();
        invalidate();
        if (onDrawStateChangedListener != null)
            onDrawStateChangedListener.clearDraw();
    }

    public void ca() {
        isCa = !isCa;
    }

    public void repeal() {
        //实际将Bitmap清空,上一次的所有Path重新绘制一次,刷新视图
        cacheCanvas.drawColor(backgroundColor);
        if (lastPaths.size() > 0) {
            removePaths.add(lastPaths.remove(lastPaths.size() - 1));
            int color = paint.getColor();
            float width = paint.getStrokeWidth();
            for (LastPath lastPath : lastPaths) {
                paint.setColor(lastPath.color);
                paint.setStrokeWidth(lastPath.width);
                cacheCanvas.drawPath(lastPath.path, paint);
            }
            paint.setColor(color);
            paint.setStrokeWidth(width);
        }
        if (onDrawStateChangedListener != null)
            onDrawStateChangedListener.reform(true);

        invalidate();
    }

    public void reform() {
        int color = paint.getColor();
        float width = paint.getStrokeWidth();
        if (removePaths.size() > 0) {
            LastPath path = removePaths.remove(removePaths.size() - 1);
            paint.setColor(path.color);
            paint.setStrokeWidth(path.width);
            cacheCanvas.drawPath(path.path, paint);
            lastPaths.add(path);
        }
        paint.setColor(color);
        paint.setStrokeWidth(width);
        invalidate();
    }

    //保存可能很慢
    public void saveBitmap(final String path) {
        //开始保存
        new Thread() {
            @Override
            public void run() {
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(path);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                cacheBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                path.lineTo(x, y);
                break;
            case MotionEvent.ACTION_UP:
                //讲这个path直接绘制到Bitmap
                if (isCa) {
                    cacheCanvas.drawPath(path, caPaint);
                    //重置
                    path.reset();
                } else {
                    cacheCanvas.drawPath(path, paint);
                    //重置
                    lastPaths.add(new LastPath(new Path(path), paint.getColor(), paint.getStrokeWidth()));
                    path.reset();
                }
                if (onDrawStateChangedListener != null)
                    onDrawStateChangedListener.startDraw();
                removePaths.clear();
                break;
        }
        invalidate();
        return true;
    }

    //返回上一次操作
    List<LastPath> lastPaths = new ArrayList<>();
    //重复上一次操作
    List<LastPath> removePaths = new ArrayList<>();


    class LastPath {
        //路径
        Path path;
        int color;
        float width;

        public LastPath(Path path, int color, float width) {
            this.path = path;
            this.color = color;
            this.width = width;
        }
    }


    public interface OnDrawStateChangedListener {

        void startDraw();

        void clearDraw();

        void reform(boolean b);
    }

    OnDrawStateChangedListener onDrawStateChangedListener;

    public void setOnDrawStateChangedListener(OnDrawStateChangedListener onDrawStateChangedListener) {
        this.onDrawStateChangedListener = onDrawStateChangedListener;
    }
}

SelectColorDialog 类


public class SelectColorDialog extends Dialog {

    private final ColorView.OnColorSelectListener listener;

    public SelectColorDialog(Context context, @NonNull ColorView.OnColorSelectListener listener) {
        super(context);
        this.listener = listener;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        ColorView view = new ColorView(getContext());
        view.setOnColorSelectListener(listener);
        setContentView(view);
    }
}

WidthDialog 类

public class WidthDialog extends Dialog {


    private final SeekBar.OnSeekBarChangeListener listener;

    public WidthDialog(Context context, @NonNull SeekBar.OnSeekBarChangeListener listener) {
        super(context);
        this.listener = listener;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        LinearLayout layout = new LinearLayout(getContext());
        SeekBar seekBar = new SeekBar(getContext());
        seekBar.setMax(9);//1-9
        seekBar.setOnSeekBarChangeListener(listener);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(200, ViewGroup.LayoutParams.WRAP_CONTENT);
        seekBar.setLayoutParams(params);
        layout.addView(seekBar);
        setContentView(layout);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.lesson12_drawview.MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="绘画板"
            android:textColor="@android:color/white" />

        <ImageView
            android:id="@+id/iv_menu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:src="@mipmap/menu_wirte" />

    </RelativeLayout>

    <com.example.administrator.lesson12_drawview.DrawView
        android:id="@+id/drawview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

popup_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/menu_item_bg"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <TextView
        android:id="@+id/pop_tv_color"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="画笔颜色"
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/pop_tv_width"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="画笔粗细"
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/pop_tv_clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="清除绘画"
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/pop_tv_ca"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="橡皮檫"
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/pop_tv_repeal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:padding="10dp"
        android:text="撤销"
        android:textColor="@color/textenable"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/pop_tv_reform"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:padding="10dp"
        android:text="重做"
        android:textColor="@color/textenable"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/pop_tv_save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:padding="10dp"
        android:text="保存绘制"
        android:textColor="@color/textenable"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@android:color/white" />

</LinearLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值