22. “我”模块(二)之涂鸦

上一节对“我”模块(一)进行了综述(可参见 “我”模块(一) 进行了解),接下来将从“我”模块(二)开始详细介绍:

知识点

  • 掌握“日历”界面的开发,使用日历展示当前年份
  • 掌握“星座”界面的开发,选择不同的星座展示不同的运势
  • 掌握“涂鸦”界面的开发,实现图画的绘制功能
  • 掌握“地图”界面的开发,可以定位一个指定地点

涂鸦

任务综述:
“涂鸦”界面样式是一个对话框,界面上主要展示“画板” “撤销” “清除” “按钮” “保存” “画笔” 以及 “橡皮檫”按钮,点击“画笔”可以选择不同颜色与粗细的画笔。点击“撤销” “清除” “保存” “橡皮檫”时,会产生对应功能的效果。

12. “涂鸦”界面

任务分析:
“涂鸦”界面主要展示“画板” “撤销” “清除” “保存” “画笔” 以及“橡皮檫”按钮,界面效果如图所示。

10186693-a6d93067ed19115b.png
“涂鸦”界面

任务实施:
(1)创建“涂鸦”界面:ScrawActivity & activity_scraw。

(2)导入界面图片(12个)。

(3)放置界面控件。

activity_scraw.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="400dp"
    android:orientation="vertical">
    <FrameLayout
        android:id="@+id/tuya_layout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="45dp">
        <ImageView
            android:id="@+id/imageview_background"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#C9DDFE" />
        <com.itheima.topline.view.ScrawView
            android:id="@+id/tuyaView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent" />
    </FrameLayout>
    <LinearLayout
        android:id="@+id/ScrollView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="46.67dp"
        android:orientation="vertical"
        android:visibility="gone">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/colortag"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@drawable/tuya_selectedtrue"
                android:onClick="onClick"
                android:text="颜色"
                android:textColor="#606060"
                android:textSize="16.67dp" />
            <Button
                android:id="@+id/bigtag"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@drawable/tuya_selectedfalse"
                android:onClick="onClick"
                android:text="大小"
                android:textColor="#606060"
                android:textSize="16.67dp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="#c5d0d5"
            android:orientation="horizontal">
            <RelativeLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="12dp"
                android:layout_marginTop="7.33dp"
                android:orientation="horizontal">
                <ImageView
                    android:id="@+id/imageviewleft"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="6.67dp"
                    android:background="@drawable/tuya_toleft" />
                <ImageView
                    android:id="@+id/imageviewright"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true"
                    android:layout_marginRight="6.67dp"
                    android:background="@drawable/tuya_toright" />
                <include layout="@layout/tuya_colorlayout" />
                <!-- 壁画粗细 -->
                <ScrollView
                    android:id="@+id/scrollviewbig"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="19.33dp"
                    android:layout_marginRight="19.33dp"
                    android:layout_marginTop="2.67dip"
                    android:fadingEdge="none"
                    android:scrollbars="none"
                    android:visibility="gone">
                    <com.itheima.topline.view.MyHorizontalScrollView
                        android:id="@+id/HorizontalScrollView02"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:scrollbars="none">
                        <LinearLayout
                            android:id="@+id/LinearLayout02"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:orientation="horizontal">
                            <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="7.33dp"
                                android:orientation="horizontal">
                                <Button
                                    android:id="@+id/sizebutton01"
                                    android:layout_width="40dp"
                                    android:layout_height="40dp" />
                                <LinearLayout
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:orientation="horizontal">
                                    <ImageView
                                        android:layout_width="33.33dp"
                                        android:layout_height="33.33dp"
                                        android:layout_gravity="center_vertical"
                                        android:layout_marginLeft="3.33dp"
                                        android:background="@drawable/tuya_brushsizebg" />
                                </LinearLayout>
                            </RelativeLayout>
                            <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="7.33dp"
                                android:orientation="horizontal">
                                <Button
                                    android:id="@+id/sizebutton02"
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:background="#aaaa00" />
                                <LinearLayout
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:orientation="horizontal">
                                    <ImageView
                                        android:layout_width="26dp"
                                        android:layout_height="26dp"
                                        android:layout_gravity="center_vertical"
                                        android:layout_marginLeft="6.67dp"
                                        android:background="@drawable/tuya_brushsizebg" />
                                </LinearLayout>
                            </RelativeLayout>
                            <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="7.33dp"
                                android:orientation="horizontal">
                                <Button
                                    android:id="@+id/sizebutton03"
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:background="@null" />
                                <LinearLayout
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:orientation="horizontal">
                                    <ImageView
                                        android:layout_width="20dp"
                                        android:layout_height="20dp"
                                        android:layout_gravity="center_vertical"
                                        android:layout_marginLeft="10dp"
                                        android:background="@drawable/tuya_brushsizebg" />
                                </LinearLayout>
                            </RelativeLayout>
                            <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="6dp"
                                android:orientation="horizontal">
                                <Button
                                    android:id="@+id/sizebutton04"
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:background="@null" />
                                <LinearLayout
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:orientation="horizontal">
                                    <ImageView
                                        android:layout_width="13.33dp"
                                        android:layout_height="13.33dp"
                                        android:layout_gravity="center_vertical"
                                        android:layout_marginLeft="13.33dp"
                                        android:background="@drawable/tuya_brushsizebg" />
                                </LinearLayout>
                            </RelativeLayout>
                            <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="6dp"
                                android:orientation="horizontal">
                                <Button
                                    android:id="@+id/sizebutton05"
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:background="@null" />
                                <LinearLayout
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:orientation="horizontal">
                                    <ImageView
                                        android:layout_width="6.67dp"
                                        android:layout_height="6.67dp"
                                        android:layout_gravity="center_vertical"
                                        android:layout_marginLeft="16.67dp"
                                        android:background="@drawable/tuya_brushsizebg" />
                                </LinearLayout>
                            </RelativeLayout>
                            <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="5.33dp"
                                android:orientation="horizontal">
                                <Button
                                    android:id="@+id/sizebutton06"
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:background="@null" />
                                <LinearLayout
                                    android:layout_width="40dp"
                                    android:layout_height="40dp"
                                    android:orientation="horizontal">
                                    <ImageView
                                        android:layout_width="3.33dp"
                                        android:layout_height="3.33dp"
                                        android:layout_gravity="center_vertical"
                                        android:layout_marginLeft="18.67dp"
                                        android:background="@drawable/tuya_brushsizebg" />
                                </LinearLayout>
                            </RelativeLayout>
                        </LinearLayout>
                    </com.itheima.topline.view.MyHorizontalScrollView>
                </ScrollView>
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/linearlayout"
        android:layout_width="fill_parent"
        android:layout_height="55dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:background="@drawable/tuya_bgbottominit"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginTop="15dp"
                android:layout_weight="1"
                android:gravity="center_horizontal|bottom"
                android:orientation="horizontal">
                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:orientation="vertical">
                    <Button
                        android:id="@+id/btn_clear"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_gravity="center"
                        android:background="@drawable/clear_icon"
                        android:onClick="onClick" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginTop="15dp"
                android:layout_weight="1"
                android:orientation="horizontal">
                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:orientation="vertical">
                    <Button
                        android:id="@+id/button_undo"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_gravity="center"
                        android:background="@drawable/undo_icon"
                        android:onClick="onClick" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginTop="15dp"
                android:layout_weight="2"
                android:orientation="horizontal">
                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:orientation="vertical">
                    <Button
                        android:id="@+id/btn_save"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_gravity="center"
                        android:background="@drawable/save_icon"
                        android:onClick="onClick" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginTop="15dp"
                android:layout_weight="1"
                android:orientation="horizontal">
                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:orientation="vertical">
                    <Button
                        android:id="@+id/button_pen"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_gravity="center"
                        android:background="@drawable/pen_icon"
                        android:onClick="onClick" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginTop="15dp"
                android:layout_weight="1"
                android:orientation="horizontal">
                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:orientation="vertical">
                    <Button
                        android:id="@+id/button_eraser"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_gravity="center_horizontal|bottom"
                        android:background="@drawable/eraser_icon"
                        android:onClick="onClick" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

(4)自定义画布。由于需要设置画布和画笔,并且需要实现撤销、清除、保存、橡皮檫等功能,因此需要在view包中创建一个ScrawView类继承View类。

ScrawView.java

public class ScrawView extends View {
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;  //画布的画笔
    private Paint mPaint;        //真实的画笔
    private float mX, mY;        //临时点坐标
    private static final float TOUCH_TOLERANCE = 4;
    //保存Path路径的集合,用List集合来模拟栈,用于后退步骤
    private static List<DrawPath> savePath;
    //保存Path路径的集合,用List集合来模拟栈,用于前进步骤
    private static List<DrawPath> canclePath;
    private DrawPath dp;                     //记录Path路径的对象
    private int screenWidth, screenHeight;//屏幕长宽
    private class DrawPath {
        public Path path;    //路径
        public Paint paint; //画笔
    }
    public static int color = Color.parseColor("#fe0000"); //背景颜色
    public static int srokeWidth = 15;
    private void init(int w, int h) {
        screenWidth = w;
        screenHeight = h;
        mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
                Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap); //保存一次一次绘制出来的图形
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        initPaint();
        savePath = new ArrayList<DrawPath>();
        canclePath = new ArrayList<DrawPath>();
    }
    private void initPaint() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND); //设置外边缘
        mPaint.setStrokeCap(Paint.Cap.ROUND);   //形状
        mPaint.setStrokeWidth(srokeWidth);      //画笔宽度
        mPaint.setColor(color);
    }
    public ScrawView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        init(dm.widthPixels, dm.heightPixels);
    }
    public ScrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        init(dm.widthPixels, dm.heightPixels);
    }
    @Override
    public void onDraw(Canvas canvas) {
        //将前面已经画过得显示出来
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        if (mPath != null) {
            //实时的显示
            canvas.drawPath(mPath, mPaint);
        }
    }
    private void touch_start(float x, float y) {
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(mY - y);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            //从x1,y1到x2,y2画一条贝塞尔曲线,更平滑(直接用mPath.lineTo也是可以的)
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }
    private void touch_up() {
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        //将一条完整的路径保存下来(相当于入栈操作)
        savePath.add(dp);
        mPath = null;      //重新置空
    }
    public void clear() { //清除画布
        mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
                Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmap);  //重新设置画布,相当于清空画布
        invalidate();
    }
    /**
     * 撤销的核心思想就是将画布清空,将保存下来的Path路径最后一个移除掉,重新将路径画在画布上面。
     */
    public int undo() {
        mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
                Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmap); //重新设置画布,相当于清空画布
        //清空画布,但是如果图片有背景的话,则使用上面的重新初始化的方法,用该方法会将背景清空掉…
        if (savePath != null && savePath.size() > 0) {
            DrawPath dPath = savePath.get(savePath.size() - 1);
            canclePath.add(dPath);
            //移除最后一个path,相当于出栈操作
            savePath.remove(savePath.size() - 1);
            Iterator<DrawPath> iter = savePath.iterator();
            while (iter.hasNext()) {
                DrawPath drawPath = iter.next();
                mCanvas.drawPath(drawPath.path, drawPath.paint);
            }
            invalidate();//刷新
        } else {
            return -1;
        }
        return savePath.size();
    }
    /**
     * 重做的核心思想就是将撤销的路径保存到另外一个集合里面(栈), 然后从redo集合中取出最顶端对象,
     * 画在画布上面即可。
     */
    public int redo() {
        //如果撤销你懂了的话,那就试试重做吧。
        if (canclePath.size() < 1)
            return canclePath.size();
        mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
                Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmap); //重新设置画布,相当于清空画布
        //清空画布,但是如果图片有背景的话,则使用上面的重新初始化的方法,用该方法会将背景清空掉…
        if (canclePath != null && canclePath.size() > 0) {
            //移除最后一个path,相当于出栈操作
            DrawPath dPath = canclePath.get(canclePath.size() - 1);
            savePath.add(dPath);
            canclePath.remove(canclePath.size() - 1);
            Iterator<DrawPath> iter = savePath.iterator();
            while (iter.hasNext()) {
                DrawPath drawPath = iter.next();
                mCanvas.drawPath(drawPath.path, drawPath.paint);
            }
            invalidate();//刷新
        }
        return canclePath.size();
    }
    public void saveBitmap(Context context) throws Exception {
        File appDir = new File(Environment.getExternalStorageDirectory(), "tuyaimg");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String filename = new SimpleDateFormat("yyyyMMddhhmmss", Locale.getDefault())
                .format(new Date(System.currentTimeMillis())); //产生时间戳,称为文件名
        File file = new File(appDir, filename + ".png");
        file.createNewFile();
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //以100%的品质创建png图片
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
        fileOutputStream.flush();
        fileOutputStream.close();
        Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show();
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                initPaint();
                canclePath = new ArrayList<DrawPath>(); //重置下一步操作
                mPath = new Path();   //每次down下去重新new一个Path
                dp = new DrawPath(); //每一次记录的路径对象是不一样的
                dp.path = mPath;
                dp.paint = mPaint;
                touch_start(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                invalidate();
                break;
        }
        return true;
    }
}

(5)自定义水平滑动控件。由于画笔需要水平滑动选择颜色,因此需要在view包中创建一个MyHorizontalScrollView类继承HorizontalScrollView类。

MyHorizontalScrollView.java

public class MyHorizontalScrollView extends HorizontalScrollView {
    public MyHorizontalScrollView(Context context) {
        super(context);
    }
    public MyHorizontalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        View view = (View) getChildAt(getChildCount() - 1);
        if (view.getLeft() - getScrollX() == 0) {   //如果为0,证明滑动到最左边
            onScrollListener.onLeft();
            Log.d("TAG", "最左边");
            //如果为0证明滑动到最右边
        } else if ((view.getRight() - (getWidth() + getScrollX())) == 0) {
            onScrollListener.onRight();
            Log.d("TAG", "最右边");
        } else {   //说明在中间
            onScrollListener.onScroll();
            Log.d("TAG", "中间");
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }
    private OnScrollListener onScrollListener;
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }
    public interface OnScrollListener {
        void onRight();
        void onLeft();
        void onScroll();
    }
}

13. 涂鸦颜色选择界面

任务分析:
在“涂鸦”界面点击画笔会显示画笔颜色与画笔大小的选择界面,点击“颜色”按钮会显示12种画笔颜色以供选择,界面效果如图所示。

10186693-6dbbbff87ff63a69.png
涂鸦颜色选择界面

任务实施:
(1)创建涂鸦选择界面:tuya_colorlayout.xml。

(2)导入界面图片(2个,tuya_colorinit、tuya_colorselected)。

(3)放置界面控件。

tuya_colorlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollviewcolor"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="19.33dp"
    android:layout_marginRight="19.33dp"
    android:fadingEdge="none"
    android:scrollbars="none">
    <com.itheima.topline.view.MyHorizontalScrollView
        android:id="@+id/HorizontalScrollView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none">
        <LinearLayout
            android:id="@+id/LinearLayout02"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            1
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview01"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button01"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#140c09" />
            </RelativeLayout>
            2
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview02"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button02"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dip"
                    android:background="#fe0000" />
            </RelativeLayout>
            3
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview03"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button03"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#ff00ea" />
            </RelativeLayout>
            4
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview04"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button04"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#011eff" />
            </RelativeLayout>
            5
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview05"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button05"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#00ccff" />
            </RelativeLayout>
            6
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview06"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button06"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#00641c" />
            </RelativeLayout>
            7
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview07"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button07"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#9bff69" />
            </RelativeLayout>
            8
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview08"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button08"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#f0ff00" />
            </RelativeLayout>
            9
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview09"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button09"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#ff9c00" />
            </RelativeLayout>
            10
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview10"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button10"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#ff5090" />
            </RelativeLayout>
            11
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview11"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button11"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#9e9e9e" />
            </RelativeLayout>
            12
            <RelativeLayout
                android:layout_width="42.67dp"
                android:layout_height="42.67dp"
                android:layout_marginLeft="4dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorinit" />
                <ImageView
                    android:id="@+id/imageview12"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:background="@drawable/tuya_colorselected" />
                <Button
                    android:id="@+id/button12"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="1dp"
                    android:background="#f5f5f5" />
            </RelativeLayout>
        </LinearLayout>
    </com.itheima.topline.view.MyHorizontalScrollView>
</ScrollView>

需要注意的是,由于该布局文件需要显示12种颜色,有12个类似的相对布局,因此需要在该布局文件中用数字提示这是第几种颜色的布局。

14. 创建ColorsBean

任务分析:
在“涂鸦”界面点击“画笔”会显示画笔颜色,画笔颜色的属性包括颜色对应的按钮、颜色对应按钮的背景、按钮的Id以及颜色的名称。为了便于后续对这些属性进行操作,因此需要创建一个ColorsBean类存放画笔颜色的属性。

ColorsBean.java

public class ColorsBean {
    private Button button;         //颜色所在的按钮
    private ImageView buttonbg;   //颜色所在的按钮的背景
    private int tag;                //按钮的Id
    private String name;           //颜色名称
    public Button getButton() {
        return button;
    }
    public void setButton(Button button) {
        this.button = button;
    }
    public ImageView getButtonbg() {
        return buttonbg;
    }
    public void setButtonbg(ImageView buttonbg) {
        this.buttonbg = buttonbg;
    }
    public int getTag() {
        return tag;
    }
    public void setTag(int tag) {
        this.tag = tag;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

15. 创建BigSizeBean

任务分析:
在“涂鸦”界面点击画笔会显示选择画笔大小,画笔大小的属性包括画笔大小对应的按钮、画笔大小对应按钮的Id以及画笔的大小。为了便于后续对这些属性进行操作,因此创建一个BigBean类存放画笔大小的属性。

任务实施:
创建BigSizeBean类(bean包),在该类中创建画笔大小所需的属性。

BigSizeBean.java

public class BigSizeBean {
    private Button button;  //选择画笔的大小所在的按钮
    private int tag;         //画笔大小所在的按钮的Id
    private int name;       //画笔的大小
    public Button getButton() {
        return button;
    }
    public void setButton(Button button) {
        this.button = button;
    }
    public int getTag() {
        return tag;
    }
    public void setTag(int tag) {
        this.tag = tag;
    }
    public int getName() {
        return name;
    }
    public void setName(int name) {
        this.name = name;
        int i = Color.RED;
    }
}

16. “涂鸦”界面逻辑代码

任务分析:
“涂鸦”界面主要展示清除、撤销、保存、画笔、画笔颜色选择、画笔大小选择、橡皮檫等图标,当点击“清除”图标时会清除画板上的涂鸦,点击“撤销”“保存”“橡皮檫”图标时会分别撤销、保存、拆除画板上的涂鸦,当点击“画笔”图标时,会弹出画笔大小选择以及画笔选择的窗口。

任务实施:
(1)获取界面控件。在ScrawActivity中创建界面控件的初始化方法initView(),用于获取涂鸦界面所要用到的控件。

(2)相关按钮的点击事件。在ScrawActivity中实现OnClickListener与OnScrollListener接口并重写onClick()方法,在该方法中设置清除、撤销、保存、橡皮檫、画笔、画笔颜色、画笔大小等功能。

(3)初始化画笔颜色与大小。在ScrawActivity中创建initColorButton()方法用于初始化画笔颜色与画笔大小的数据。

ScrawActivity.java

public class ScrawActivity extends AppCompatActivity implements View.OnClickListener,
        MyHorizontalScrollView.OnScrollListener {
    private ImageView imageview_background;
    private ScrawView tuyaView;
    FrameLayout tuyaFrameLayout =null;
    private static final int UNDO_PATH = 1;
    private static final int REDO_PATH = 2;
    private static final int USE_ERASER = 3;
    private static final int USE_PAINT = 4;
    private LinearLayout linearlayout;
    private Button colortag;
    private Button bigtag;
    private ScrollView scrollviewcolor;
    private ScrollView scrollviewbig;
    private MyHorizontalScrollView hscrollViewcolor;
    private MyHorizontalScrollView hscrollViewsize;
    private List<ColorsBean> colors = new ArrayList();
    private ColorsBean color;
    private List<BigSizeBean> sizes = new ArrayList();
    private BigSizeBean size;
    private int index;
    private int CANCLE_BACKGROUND_IMAGE = 0;
    private final int defaultColor= Color.parseColor("#C9DDFE");
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scraw);
        initView();
    }
    private void initView(){
        tuyaFrameLayout =(FrameLayout) findViewById(R.id.tuya_layout);
        imageview_background = (ImageView) findViewById(R.id.imageview_background);
        tuyaView=(ScrawView)findViewById(R.id.tuyaView);
        colortag = (Button)this.findViewById(R.id.colortag);
        bigtag = (Button)this.findViewById(R.id.bigtag);
        scrollviewcolor = (ScrollView)this.findViewById(R.id.scrollviewcolor);
        scrollviewbig = (ScrollView)this.findViewById(R.id.scrollviewbig);
        hscrollViewcolor = (MyHorizontalScrollView)this.findViewById(R.id.
                HorizontalScrollView01);
        hscrollViewcolor.setOnScrollListener(this);
        hscrollViewsize = (MyHorizontalScrollView)this.findViewById(R.id.
                HorizontalScrollView02);
        hscrollViewsize.setOnScrollListener(this);
        linearlayout = (LinearLayout)this.findViewById(R.id.ScrollView01);
        initColorButton();
    }


    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UNDO_PATH:
                    int undo = tuyaView.undo(); //撤销上次操作
                    System.out.println("可以撤销:"+undo);
                    if(undo<0){
                        CANCLE_BACKGROUND_IMAGE ++;
                        switch (CANCLE_BACKGROUND_IMAGE) {
                            case 0:
                                break;
                            case 1:
                                System.out.println("设置imageview为默认");
                                imageview_background.setBackgroundColor(defaultColor);
                                imageview_background.setImageBitmap(null);
                                CANCLE_BACKGROUND_IMAGE =0;
                                break;
                        }
                    }
                    break;
                case REDO_PATH:
                    int redo = tuyaView.redo(); //返回上次操作
                    System.out.println("可以前进:"+ redo);
                    if(redo<1){
                        //设置按钮不可用
                    }
                    break;
                case USE_ERASER:
                    if(linearlayout.getVisibility()==View.VISIBLE){
                        linearlayout.setVisibility(View.GONE);
                    }
                    ScrawView.color= Color.parseColor("#C9DDFE");
                    ScrawView.srokeWidth = 15;
                    break;
                case USE_PAINT:
                    if(linearlayout.getVisibility()==View.GONE){
                        linearlayout.setVisibility(View.VISIBLE);
                        ScrawView.srokeWidth = sizes.get(index).getName()+10;
                        for(int i=0;i<colors.size();i++){
                            if(colors.get(i).getButtonbg().getVisibility()==View.VISIBLE){
                                ScrawView.color = Color.parseColor("#"+colors.get(i).
                                        getName());
                                break;
                            }
                        }
                    }else{
                        linearlayout.setVisibility(View.GONE);
                    }
                    break;
            }
        }
    };
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_undo:   //撤销
                Message undo_message = new Message();
                undo_message.what = UNDO_PATH;
                handler.sendMessage(undo_message);
                break;
            case R.id.button_eraser://橡皮擦
                Message eraser_message = new Message();
                eraser_message.what = USE_ERASER;
                handler.sendMessage(eraser_message);
                break;
            case R.id.button_pen:   //画笔
                Message pen_message = new Message();
                pen_message.what = USE_PAINT;
                handler.sendMessage(pen_message);
                break;
            case R.id.colortag:    //画笔颜色
                if(linearlayout.getVisibility()==View.VISIBLE){
                    scrollviewcolor.setVisibility(View.VISIBLE);
                    scrollviewbig.setVisibility(View.GONE);
                    colortag.setBackgroundResource(R.drawable.tuya_selectedtrue);
                    bigtag.setBackgroundResource(R.drawable.tuya_selectedfalse);
                }
                break;
            case R.id.bigtag:     //画笔粗细
                if(linearlayout.getVisibility()==View.VISIBLE){
                    scrollviewcolor.setVisibility(View.GONE);
                    scrollviewbig.setVisibility(View.VISIBLE);
                    bigtag.setBackgroundResource(R.drawable.tuya_selectedtrue);
                    colortag.setBackgroundResource(R.drawable.tuya_selectedfalse);
                }
                break;
            case R.id.btn_clear: //清除画布
                tuyaView.clear();
                break;
            case R.id.btn_save: //保存
                try {
                    tuyaView.saveBitmap(ScrawActivity.this); //保存涂鸦信息
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
        }
        //颜色
        int j = -1;
        for(int i=0;i<colors.size();i++){
            if(v.getId()==colors.get(i).getTag()){
                j=i;
            }
        }
        if (j != -1) {
            for (int i = 0; i < colors.size(); i++) {
                colors.get(i).getButtonbg().setVisibility(View.INVISIBLE);
            }
            colors.get(j).getButtonbg().setVisibility(View.VISIBLE);
            //改变颜色
            colors.get(j).getName();
            ScrawView.color = Color.parseColor("#"+colors.get(j).getName());
            return;
        }
        //大小
        for(int i=0;i<sizes.size();i++){
            if(v.getId()==sizes.get(i).getTag()){
                j=i;
            }
        }
        if (j != -1) {
            for (int i = 0; i < sizes.size(); i++) {
                sizes.get(i).getButton().setBackgroundResource(0);
            }
            sizes.get(j).getButton().setBackgroundResource(R.drawable.
                    tuya_brushsizeselectedbg);
            //改变大小
            sizes.get(j).getName();
            ScrawView.srokeWidth=sizes.get(j).getName()+10;
            index = j;
            return;
        }
    }
    @Override
    public void onRight() {
    }
    @Override
    public void onLeft() {
    }
    @Override
    public void onScroll() {
    }
    private void initColorButton() {
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button01));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview01));
        color.setName("140c09");
        color.setTag(R.id.button01);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button02));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview02));
        color.setName("fe0000");
        color.setTag(R.id.button02);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button03));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview03));
        color.setName("ff00ea");
        color.setTag(R.id.button03);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button04));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview04));
        color.setName("011eff");
        color.setTag(R.id.button04);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button05));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview05));
        color.setName("00ccff");
        color.setTag(R.id.button05);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button06));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview06));
        color.setName("00641c");
        color.setTag(R.id.button06);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button07));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview07));
        color.setName("9bff69");
        color.setTag(R.id.button07);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button08));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview08));
        color.setName("f0ff00");
        color.setTag(R.id.button08);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button09));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview09));
        color.setName("ff9c00");
        color.setTag(R.id.button09);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button10));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview10));
        color.setName("ff5090");
        color.setTag(R.id.button10);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button11));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview11));
        color.setName("9e9e9e");
        color.setTag(R.id.button11);
        colors.add(color);
        color = new ColorsBean();
        color.setButton((Button)this.findViewById(R.id.button12));
        color.setButtonbg((ImageView)this.findViewById(R.id.imageview12));
        color.setName("f5f5f5");
        color.setTag(R.id.button12);
        colors.add(color);
        for(int i=0;i<colors.size();i++){
            colors.get(i).getButton().setOnClickListener(this);
            colors.get(i).getButtonbg().setVisibility(View.INVISIBLE);
        }
        colors.get(1).getButtonbg().setVisibility(View.VISIBLE);
        size = new BigSizeBean();
        size.setButton((Button)this.findViewById(R.id.sizebutton01));
        size.setName(15);
        size.setTag(R.id.sizebutton01);
        sizes.add(size);
        size = new BigSizeBean();
        size.setButton((Button)this.findViewById(R.id.sizebutton02));
        size.setName(10);
        size.setTag(R.id.sizebutton02);
        sizes.add(size);
        size = new BigSizeBean();
        size.setButton((Button)this.findViewById(R.id.sizebutton03));
        size.setName(5);
        size.setTag(R.id.sizebutton03);
        sizes.add(size);
        size = new BigSizeBean();
        size.setButton((Button)this.findViewById(R.id.sizebutton04));
        size.setName(0);
        size.setTag(R.id.sizebutton04);
        sizes.add(size);
        size = new BigSizeBean();
        size.setButton((Button)this.findViewById(R.id.sizebutton05));
        size.setName(-5);
        size.setTag(R.id.sizebutton05);
        sizes.add(size);
        size = new BigSizeBean();
        size.setButton((Button)this.findViewById(R.id.sizebutton06));
        size.setName(-10);
        size.setTag(R.id.sizebutton06);
        sizes.add(size);
        for(int i=0;i<sizes.size();i++){
            sizes.get(i).getButton().setOnClickListener(this);
            sizes.get(i).getButton().setBackgroundResource(0);
        }
        sizes.get(2).getButton().setBackgroundResource(R.drawable.
                tuya_brushsizeselectedbg);
        index = 2;
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ScrawView.color = Color.parseColor("#fe0000");
        ScrawView.srokeWidth = 15;
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            if(linearlayout.getVisibility()==View.VISIBLE){
                linearlayout.setVisibility(View.GONE);
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }
}

(4)修改清单文件。由于“涂鸦”界面是对话框的样式,因此也需要给该界面添加对话框的样式:

        <activity
            android:name=".activity.ScrawActivity"
            android:theme="@style/AppTheme.NoTitle.Dialog" />

(5)修改“我”界面逻辑代码。由于点击“我”界面上的涂鸦图标会跳转到“涂鸦”界面,因此需要在MeFragment中的onClick()方法,在该方法中的“case R.id.ll_scraw:”语句下方添加如下代码:

 Intent scarwIntent = new Intent(getActivity(), ScrawActivity.class);
 startActivity(scarwIntent);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值