有关Color和Drawable你所不知道的那些内容

来源:互联网 发布:登录qq游戏网络异常 编辑:程序博客网 时间:2024/06/08 08:40

Android开发中,我们经常会用到Color或Drawable,有时他们是可以混用的,有时却有严格的区别。

Drawable

体系结构

Drawable是可绘制物件的一般抽象。与View不同,Drawable上没有事件和交互方法。我们经常会自定义View来实现一些复杂或绚丽的UI效果,其实也可以自定义Drawable来实现。
Drawable本身是一个抽象类,我们一般使用的是它的子类,都在android.graphics.drawable包下。有BitmapLevelsNinePatchScaleShapeLayersStates等等。

原理

draw(Canvas canvas)Drawable必须附在一个View上,绘制成什么样子,setBounds()来决定大小,由view的draw方法来绘制Drawable的子类。

圆角和圆形Drawable(头像)

自定义Drawable很容易实现圆角和圆形图片,先看效果图:
Round-Circle

/** * 圆角图片 * Created by dengpan on 16/4/21. */public class RoundRectImageDrawable extends Drawable {    private RectF rectF;    private Paint mPaint;    private Bitmap bitmap;    public RoundRectImageDrawable(Bitmap bitmap) {        this.bitmap = bitmap;        //表示图片太大,则填充。TileMode还有repeat、mirror,表示重复        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setShader(bitmapShader);        rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());    }    @Override    public void setBounds(int left, int top, int right, int bottom) {        super.setBounds(left, top, right, bottom);        rectF = new RectF(left, top, right, bottom);    }    @Override    public void draw(Canvas canvas) {        //60表示圆角的半径        canvas.drawRoundRect(rectF, 60, 60, mPaint);    }    @Override    public void setAlpha(int alpha) {    }    @Override    public void setColorFilter(ColorFilter colorFilter) {    }    @Override    public int getOpacity() {        return 0;    }    //设置下面两个方法,保证原图可以完整的显示出来。    @Override    public int getIntrinsicWidth() {        return bitmap.getWidth();    }    @Override    public int getIntrinsicHeight() {        return bitmap.getHeight();    }}

下面是圆形Drawable:

/** * 圆形图片(头像) * Created by dengpan on 16/4/21. */public class CircleDrawable extends Drawable {    private int mWidth;    private RectF rectF;    private Paint mPaint;    private Bitmap bitmap;    public CircleDrawable(Bitmap bitmap) {        this.bitmap = bitmap;        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setShader(bitmapShader);        rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());        mWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());    }    @Override    public void setBounds(int left, int top, int right, int bottom) {        super.setBounds(left, top, right, bottom);        rectF = new RectF(left, top, right, bottom);        mWidth = (int) Math.min(rectF.width(), rectF.height());    }    @Override    public void draw(Canvas canvas) {        canvas.drawCircle(rectF.left + mWidth / 2, rectF.top + mWidth / 2, mWidth / 2, mPaint);    }    @Override    public void setAlpha(int alpha) {    }    @Override    public void setColorFilter(ColorFilter colorFilter) {    }    @Override    public int getOpacity() {        return 0;    }    //设置了下面两个方法的返回值,才能正常的显示完整的圆形头像,不然头像太大,就截取了左上角部分。    @Override    public int getIntrinsicWidth() {        return mWidth;    }    @Override    public int getIntrinsicHeight() {        return mWidth;    }}

调用方法:

Bitmap b = BitmapFactory.decodeResource(getResources(), R.mipmap.cute);//圆角DrawableimageView1.setImageDrawable(new RoundRectImageDrawable(b));//圆形DrawableimageView2.setImageDrawable(new CircleDrawable(b));

Shape

Shape类型是用来绘制几何图形的,易用而且轻量化。一般使用XML来使用,放在res/drawable目录下。

使用<shape>标签定义的是GradientDrawable

Shape类是个抽象类,draw(Canvas canvas, Paint paint)必须实现,onResize(float width, float height)也是非常重要的方法。它有五种子类。

子类 说明 RectShape 矩形、直角矩形、圆角矩形 OvalShape 椭圆形、圆形 PathShape 线形、环形 Ring、Line 环形、环形进度条、线形、实线、虚线 ArcShape 弧形

Shape的通用属性:

属性 值说明 shape 根标签。shape:[“rectangle”,”oval”,”ring”,”line”] ring有innerRadius[内环半径]、innerRadiusRatio、thickness[厚度]、thicknessRatio、useLevels等属性 corners radius、topLeftRadius、topRightRadius… gradient 渐变色。startColor,centerColor、endColor、angle(由type决定,如果是linear类型,则表示从什么角度渐变)、type[“linear”、”radial”、”sweep”]… padding drawable中的属性。left、top、right、bottom size width、height,决定Shape的宽高,不设置则由view的宽高决定 solid color 填充色。 stroke 边角线:width、color、dashWidth(虚线宽度)、dashGap(虚线间隔)。

例如:很容易做一个圆角的按钮背景图,不需要美工作图。

<?xml version="1.0" encoding="utf-8"?><!-- shape屬性設置形狀。 这里是矩形,也可以设置圆形(oval)--><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <!-- 圆角半径 -->    <corners android:radius="8dp" />    <!-- 填充颜色 -->    <solid android:color="#da87ef" />    <!-- 大小-->    <size        android:width="100dp"        android:height="100dp" />    <!-- padding-->    <padding        android:bottom="8dp"        android:left="8dp"        android:right="8dp"        android:top="8dp" />    <!-- 边线。这里设置的虚线。shape="line"这个是必须的属性,也可以是唯一的属性。 -->    <stroke        android:width="1dp"        android:color="@color/gray"        android:dashGap="1dp"        android:dashWidth="1dp" />    <!-- gradient -->    <!--<gradient        android:centerColor="@color/green"        android:endColor="@color/yellow"        android:gradientRadius="50dp"        android:startColor="@color/blue"        android:type="radial" />--></shape>

效果如下:
Shape-Rectangel

PathShape和ArcShape

我们可以使用代码实现Path和Arc类型的drawable,绘制不同的几何形状。
PathShape-ArcShape

ShapeDrawable shapeDrawable = null;        Path p = new Path();        p.moveTo(50,0);        p.lineTo(0,50);        p.lineTo(50,100);        p.lineTo(100,50);        p.lineTo(50,0);        p.close();        PathShape ps = new PathShape(p,100,100);        shapeDrawable = new ShapeDrawable(ps);        shapeDrawable.setBounds(0,0,100,150);        shapeDrawable.getPaint().setStyle(Paint.Style.FILL);        shapeDrawable.getPaint().setColor(Color.CYAN);        imageViewShapePath.setBackgroundDrawable(shapeDrawable);        //Arc shape        ArcShape arcShape = new ArcShape(225,270);//初始180度,逆时针旋转270度。0度在右手水平位置。        shapeDrawable = new ShapeDrawable(arcShape);        shapeDrawable.setBounds(0,0,200,200);        shapeDrawable.getPaint().setStyle(Paint.Style.FILL);        shapeDrawable.getPaint().setColor(Color.BLUE);        imageViewShapeArc.setBackgroundDrawable(shapeDrawable);        arcShape = new ArcShape(45,270);//初始180度,旋转270度。0度在右手水平位置。        shapeDrawable = new ShapeDrawable(arcShape);        shapeDrawable.setBounds(0,0,200,200);        shapeDrawable.getPaint().setStyle(Paint.Style.STROKE);        shapeDrawable.getPaint().setColor(Color.RED);        imageViewShapeRing.setBackgroundDrawable(shapeDrawable);

ShapeDrawable和ShapeDrawable.ShaderFactory

Shapedrawable直接在Java代码中使用。
Shape对象放入ShapeDrawable中,ShapeDrawables设置画笔样式。
Drawable尺寸变化时调用ShapeDrawable.ShaderFactory产生的Shader
BitmapShaderComposeShaderLinearGradientRadialGradientSweepGradient

//BitmapShadershapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {            @Override            public Shader resize(int width, int height) {                return new BitmapShader(b, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);            }        });//LinearGradientshapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {            @Override            public Shader resize(int width, int height) {                return new LinearGradient(0,0,width,height,                        new int[]{                                //可以设置多个颜色渐变,可以任意多个颜色                            Color.RED,Color.BLACK,Color.BLUE                        },null, Shader.TileMode.CLAMP);            }        });        //SweepGradient   注意:最后两个参数的数量要一致    shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {            @Override            public Shader resize(int width, int height) {                return new SweepGradient(width/2,height/2,                        new int[]{                            Color.RED,Color.YELLOW,Color.BLUE, Color.CYAN                        },new float[]{0.1f,0.3f,0.7f,1.0f});            }        });    

图片相关Drawable

BitmapDrawable

BitmapDrawable是对bitmap的一种封装。它可以设置绘制方式,使图片平铺、拉伸或保持图片原始大小。比如一些需要重复的图片,可以让美工提供很小的图片,我们使用BitmapDrawable来进行重复渲染。

属性 说明 src 只能是图片,不能是xml定义的drawable gravity antialias 是否开启抗锯齿 dither 是否抖动 filter 对图片进行滤波 tileMode repeat、mirror、clamp(边缘拉伸)、disable tint 着色 mipmap 是否可以用mipmap ,api>=17 tileModeX api>=21 tileModeY api>=21 tintMode api>=21

实现方法,有代码和xml方式:

XML方式

在res/drawable下定义bitmap drawable。

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"    android:src="@mipmap/cute"    android:tileMode="mirror"    android:dither="true"    android:antialias="true"/>

代码方式

Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.cute);BitmapDrawable bd = new BitmapDrawable(getResources(),b);bd.setAntiAlias(true);bd.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);ivBitmapPic.setImageDrawable(bd);

NinePatchDrawable

.9图片最大的特点是在拉伸不会失帧。.9图片只能用于图片拉伸的情况
也是可以res/drawable中使用<nine-patch>标签来定义一个NinePatchDrawable。不过都需要.9.png的图片。Android提供了.9图片的制作工具,在/tools目录下。

PictureDrawable

  • Picture类。android.graphics.Picture
    不存储实际的像素,仅仅记录绘制的过程。
  • PictureDrawable(Picture p)
    使用PictureDrawable,很多手机显示不出来。需要关闭对应的activity的硬件加速属性。android:hardwareAccelerated="false"
    一般在代码中实现:
Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.cute);Paint paint = new Paint();paint.setTextSize(30);Picture p = new Picture();Canvas c= p.beginRecording(b.getWidth(),b.getHeight());c.drawBitmap(b,0,0,paint);c.drawText("PictureDrawable",20,50,paint);p.endRecording();PictureDrawable drawable = new PictureDrawable(p);ivPicDrawable.setImageDrawable(drawable);

Color类型的Drawable

ColorDrawable和ColorFilter

ColorDrawable

在Android工程的res目录下有两个地方可以设置ColorDrawable,分别是drawable和values目录,使用标签来设置color。在drawable目录下设置color:
<?xml version="1.0" encoding="utf-8"?><color xmlns:android="http://schemas.android.com/apk/res/android"    android:color="#ff0000" />
在values目录下设置color:
<?xml version="1.0" encoding="utf-8"?><resources>    <color name="colorPrimary">#3F51B5</color>    <color name="colorPrimaryDark">#303F9F</color>    <color name="colorAccent">#FF4081</color>    <drawable name="colorDrawable">#000000</drawable></resources>

ColorFilter

ColorFilter有3个子类。ImageView和ImageButton、Drawable以及Paint可以设置ColorFilter。 子类ColorFilter 说明 ColorMatrixColorFilter 指定一个4*5的ColorFilter LightingColorFilter RGB颜色通道强度变换 PorterDuffColorFilter RGB色混合效果,有18种混合效果 - **ColorMatrix**![color-matrix](http://img.blog.csdn.net/20160420210249932)
private void setArgb(int alpha,int red,int green,int blue){        ColorMatrix colorMatrix = new ColorMatrix(new float[]{                red,0,0,0,0,                0,green,0,0,0,                0,0,blue,0,0,                0,0,0,alpha,0        });        drawable.setColorFilter(new ColorMatrixColorFilter(colorMatrix));        view.postInvalidate();    }
  • LightingColorFilter LightingColorFilter(int mul,int add)= (mul * 原色值 + add) % 255
//表示过滤了blue的颜色,并增强55drawable.setColorFilter(new LightingColorFilter(0x0000ff,0x000055));
  • PorterDuffColorFilter PorterDuffColorFilter(int srcColor,PorterDuff.Mode mode)
//mutate方法可以让同一个drawable在不同的控件上进行展示不同的效果。drawable.mutate().setColorFilter(new PorterDuffColorFilter(0x0000ff, PorterDuff.Mode.ADD));//18种效果。

GradientDrawable和Tint

 GradientDrawable linearGradient = new GradientDrawable();        linearGradient.setGradientType(GradientDrawable.LINEAR_GRADIENT);// RADIAL_GRADIENT,SWEEP_GRADIENT        //xml中只有startColor、centerColor和endColor,在代码中可以设置任意多个color。        linearGradient.setColors(new int[]{0xff0000, 0xff0001, 0x000ff1, 0xff2310, 0x12ff00});//API 16 above        linearGradient.setShape(GradientDrawable.RECTANGLE);//OVAL,LINE,RING        view.setBackground(linearGradient); // API 16 above

Android5.0以后,引用了Tint的功能。
android:backgroundTint , android:tint及其对应的tintMode。ImageView有这两个属性,其它的只有backgound的tint。

管理多个Drawable

LayerDrawableLevelListDrawableTransitionDrawable 它们之间有些相似性,都是管理多个 Drawable 的展示,其中 TransitionDrawable 是 LayerDrawable 的子类只管理2个 Drawable。不过,从类继承体系上分,LevelListDrawable 和 StateListDrawable 才是比较靠近的,效果也相似。

StateListDrawable

在res/drawable目录下可以定义根据View的状态(pressed,focus,checked等)的不同而显示不同drawable的drawable。这种drawable在开发中经常会用到,比如按钮点击显示按下去的背景。

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"    android:enterFadeDuration="300" android:exitFadeDuration="300">    <item android:drawable="@drawable/shape_selected" android:state_selected="true"/>    <item android:drawable="@drawable/shape_selected" android:state_pressed="true"/>    <item android:drawable="@drawable/shape_normal" /><!-- 务必将无状态放在最后 --></selector>

注意:将正常状态的drawable放到最后,不然会看不到状态变化而导致的drawable变化。因为statelist drawbale是从上到下来搜索,如果有匹配的状态,则显示对应drawable。

LayerDrawable

LayerDrawable是一个多层的Drawable,可以对每一层的drawable进行控制。从而实现一些效果。它是这样在drawable目录下定义的:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@mipmap/mv" android:left="20dp" android:top="20dp" android:id="@+id/l1"/>    <item android:drawable="@mipmap/mv" android:left="40dp" android:top="40dp" android:id="@+id/l2"/>    <item android:left="60dp" android:top="60dp"  android:id="@+id/l3">        <shape >            <gradient android:centerColor="@color/blue"></gradient>        </shape>    </item></layer-list>

可以为每一层drawable设置id,这样可以控制每一层的drawable,从而达到一些特定的效果。比如下面是将最上层的drawable隐藏掉。
Layer-Drawable
通过Drawable d1 = custLayerDrawable.findDrawableByLayerId(R.id.l1);找到某个id对应的Drawable,然后可以进行操作,比如隐藏: d1.setAlpha(0);
当然,也可以通过代码来设置一个多层的drawable。例如:

DisplayMetrics dm = getResources().getDisplayMetrics();Drawable [] ds = new Drawable[3];ds[0] = getResources().getDrawable(R.mipmap.mv);ds[1] = getResources().getDrawable(R.mipmap.mv);ds[2] = getResources().getDrawable(R.mipmap.mv);LayerDrawable layerDrawable = new LayerDrawable(ds);layerDrawable.setLayerInset(0,0,0,(int)(20 * dm.density),(int)(20 * dm.density));//第一个参数表示索引。layerDrawable.setLayerInset(1,0,0,(int)(40 * dm.density),(int)(40 * dm.density));layerDrawable.setLayerInset(2,0,0,(int)(60 * dm.density),(int)(60 * dm.density));imageViewLayer.setImageDrawable(layerDrawable);

LevelListDrawable

LevelListDrawable根据level-list中的每一个draawable的level范围来显示对应的drawable。比如在drawable目录中定义一个level-list:

<!-- 的每一个level-child表示一种不同的颜色,只在一定的level值区间显示,方便演示。 --><level-list xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/level_child" android:maxLevel="10" android:minLevel="0"/>    <item android:drawable="@drawable/level_child1" android:maxLevel="20" android:minLevel="11"/>    <item android:drawable="@drawable/level_child2" android:maxLevel="30" android:minLevel="21"/>    <item android:drawable="@drawable/level_child3" android:maxLevel="40" android:minLevel="31"/>    <item android:drawable="@drawable/level_child4" android:maxLevel="50" android:minLevel="41"/></level-list>

效果如图,当拖动seekbar改变drawable的level值时,进入到不同的level区间,则会显示不同的子drawable。
LevelList_drawable

TransitionDraeable

TransitionDraeable继承LayerDrawable,但它只能有2个子drawable。切换drawable会产生渐变动画,这时一个非常好的效果。同样,先定义drawable文件:

<transition xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/level_child4" />    <item android:drawable="@drawable/level_child5" /></transition>

然后在代码中设置开始渐变,里面的参数表示动画的时间:两个方法,一个表示正向渐变,一个表示反向渐变。

  transitionDrawable.startTransition(500);  transitionDrawable.reverseTransition(500);

效果如下:
transitionDrawable

容器类 Drawable

ClipDrawableInsetDrawableRotateDrawableScaleDrawable 都是 DrawableWrapper 的子类。它们都是容器类 Drawable,自生只能有一个子 Drawable,通过对子 Drawable 进行处理来实现 clip、inset、rotate、scale 的效果

ClipDrawable

使用<clip>标签定义ClipDrawable,在res/drawable目录中。

<!-- 水平方向裁剪、裁剪时从右到左、对gradient_progress进行裁剪--><clip xmlns:android="http://schemas.android.com/apk/res/android"    android:clipOrientation="horizontal"    android:gravity="left"    android:drawable="@drawable/gradient_progress_h"></clip>
<!-- 图片四周扩散和四周聚拢--><clip xmlns:android="http://schemas.android.com/apk/res/android"    android:clipOrientation="horizontal|vertical"    android:gravity="center"    android:drawable="@mipmap/mv"></clip>

通过在代码中设置Drawable的Level来控制裁剪效果。容器类Drawable都是通过setLevel(int level)来控制的,level值的范围是[0,10000]。

imageView.getDrawable().setLevel(10000);

效果图:
Clip-Drawable

InsetDrawable

InsetDrawable主要是为设置backgroud背景的控件的drawable设置边距,类似padding。设置方式也是在res/drawable目录下,使用<inset>标签,里面放一个drawable,然后设置四个边距。

<inset xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/inset_shape"    android:insetBottom="20dp"    android:insetLeft="20dp"    android:insetRight="20dp"    android:insetTop="20dp"></inset>

RotateDrawable

RotateDrawable很容易实现旋转的效果。比如指针转盘。同样是在res/drawable目录下,使用<rotate>标签来设定一个RotateDrawabl。

<rotate xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@mipmap/mv"    android:fromDegrees="0"    android:toDegrees="180"    android:pivotX="50%"<!-- %p表示在父控件中的百分比 -->    android:pivotY="50%"<!-- %p表示在父控件中的百分比 -->    android:visible="true"></rotate>

上面定义了一个图片,从0°-180°,以自己的中心点为中心旋转180。
Rotate-Drawable

ScaleDrawable

ScaleDrawable很容易实现缩放的效果。设置方式和上面的drawable一样。如:

<scale xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@mipmap/mv"    android:useIntrinsicSizeAsMinimum="false"    android:scaleWidth="50%"<!-- 宽度缩放比例 -->    android:scaleHeight="50%"<!-- 高度缩放比例 -->    android:scaleGravity="right|top"><!-- 缩放后的位置 --></scale>

Scale-Drawable

矢量图VectorDrawable

Android5.0(API Level 21)中引入了 VectorDrawableAnimatedVectorDrawable,矢量图不会因为图像放大而失真,而且占用内存小。所以学会矢量图并用好它,将对开发 APP 非常有用。VectorDrawable只支持部分的SVG规范。一般去找成型的SVG图片。

VectorDrawable

矢量图中保存的只是图像绘制的方法:
大写代表后面的参数是绝对坐标,小写代表相对坐标。

方法 说明 M moveTo绘制点。 L lineTo画直线 Z close开始点-结束点闭合 C cubic bezier三次贝塞尔曲线 Q quatratic bezier二次贝塞尔曲线 A 圆弧rx ry x-rotation large-arc-flag sweep-flag xy

vector

<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="60dp"    android:height="60dp"    android:viewportHeight="600"    android:viewportWidth="600">    <group        android:name="group"        android:pivotX="300.0"        android:pivotY="300.0"        android:rotation="0.0">        <path            android:name="v"            android:fillColor="@android:color/black"            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /><!-- M到300,70,然后l到0,-70 -->    </group></vector>

AnimatedVector

属于属性动画。

此篇文章是学习极客学院hexter老师的做的笔记。

3 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 慢性胃炎引起的口臭怎么办 烂牙引起的口臭怎么办 坏牙引起的口臭怎么办 牙齿拔了有口臭怎么办 胃疼连着后背疼怎么办 肚脐眼又红又痒怎么办 三岁宝宝有口臭怎么办 脚扭了按压疼痛怎么办 喝完酒头晕5天了怎么办 三岁宝宝口气重怎么办 肠镜检查出息肉怎么办 怀孕了口气很重怎么办 脚被重物压肿了怎么办 摔倒膝盖肿了应该怎么办 脚挤压伤肿了怎么办 30岁后脸上长斑怎么办 12岁脸上有雀斑怎么办 16岁脸上有斑怎么办 脸上有斑怎么办 教你 4o岁脸上有色斑怎么办 小孩三年级成绩都差怎么办 孕晚期头大腿短怎么办 天天p图格式不对怎么办 橡胶枕头太高了怎么办 信用卡多存的钱怎么办 异地三险离职了怎么办 不小心吃了沥青怎么办 快递爆仓怎么办怎么分 爱养成4酒二借钱怎么办 村里的非农户口怎么办 炖排骨肉老发硬怎么办 u盾密码忘了怎么办 创维电视不清晰怎么办 电视的屏幕裂了怎么办 种植牙牙根掉了怎么办 50多岁牙齿脱落怎么办 泡脚的木桶漏水怎么办 隔水炖锅有声音怎么办 电气两用灶坏了怎么办 蒸的米饭水多了怎么办 红掌花叶子发黄怎么办