简体   繁体   English

使用样式和属性重用具有不同值的布局-Android

[英]Reusing layout with different values using styles and attrs - Android

I have a layout border_bottom_black_bluegrey_background.xml 我有一个布局border_bottom_black_bluegrey_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
        <shape android:shape="rectangle" >
            <stroke
                android:width="1dp"
                android:color="@color/black" />
        </shape>
    </item>
    <item android:bottom="1dp">
        <shape android:shape="rectangle" >
            <solid android:color="@color/blue_grey" />
        </shape>
    </item>

</layer-list>

I'm trying to reuse this layout so that I don't have to create one for each different border and background color. 我试图重用这种布局,以便不必为每种不同的边框和背景色创建一个。

I know this can be accomplished with styles and attrs, I had a look on the internet for good tutorial but with no avail. 我知道这可以通过样式和属性来实现,我在网上查看了不错的教程,但无济于事。

This is what i've got so far: 这是到目前为止我得到的:

attrs.xml attrs.xml

<resources>
    <declare-styleable>
        <attr name="backgroundColor" format="reference"/>
        <attr name="borderColor" format="reference"/>
    </declare-styleable>
</resources>

styles.xml styles.xml

 <style name="BorderBottom">
    <item name="android:background">@drawable/border_bottom</item>
</style>

<style name="BlackBorderBlueGreyBackground" parent="BorderBottom">
    <item name="borderColor">@color/black</item>
     <item name="backgroundColor">@color/blue_grey</item>
</style>

border_bottom.xml border_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
      <shape 
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="@color/black" />
            <solid android:color="?attr/borderColor" />

        </shape>
   </item>

   <item android:bottom="1dp"> 
      <shape 
        android:shape="rectangle">
            <solid android:color="?attr/backgroundColor" />
        </shape>
   </item>

</layer-list>

My implementation of the style 我对样式的实现

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/BlackBorderBlueGreyBackground"
    android:orientation="vertical" >

</RelativeLayout>

Can someone point me in the right direction? 有人可以指出我正确的方向吗?

I think the issue is that when you use the attrs.xml that is for use in creating custom views . 我认为问题在于,当您使用用于创建自定义视图的attrs.xml时。 The problem I see with your code above is that border_bottom.xml is pointing to color attributes that have not been explicitly declared and it has no way of knowing what color it should be. 我在上面的代码中看到的问题是border_bottom.xml指向尚未显式声明的颜色属性,并且无法知道应该使用哪种颜色。 If want to create a layout that you can continuously use my suggestion would be to create a class that creates backgrounds for you and if need be you can just save the drawable created. 如果要创建一个可以连续使用的布局,我的建议是创建一个为您创建背景的类,如果需要,您可以保存创建的可绘制对象。 This is a class that I use to draw underlines under views I think it should suffice. 这是我用来在我认为足以满足要求的视图下划线的类。

public final class Background extends ShapeDrawable {
public final static int RECTANGLE = 0x00;
public final static int ROUND_RECTANGLE = 0x01;
public final static int UNDERLINE = 0x02;
    //For future use
//public final static int CIRCLE = 0x03;

private int shape_type;
private final Paint fill_paint, stroke_paint;
private int stroke_width;

private static RectShape rectangle = new RectShape();
private static RoundRectShape round_rectangle;
//private static OvalShape circle = new OvalShape();

public static final Background newInstance(int shape, int background_color, int stroke_color, int stroke_width) {
    switch (shape) {
    case UNDERLINE:
    case RECTANGLE:
        return new Background(shape, rectangle, background_color, stroke_color, stroke_width);
    case ROUND_RECTANGLE:
        round_rectangle = new RoundRectShape(new float[] { stroke_width, stroke_width,
                stroke_width, stroke_width, stroke_width, stroke_width, stroke_width, stroke_width }, null, null);

        return new Background(shape, round_rectangle, background_color, stroke_color, stroke_width);
    default:
        return null;
    }
}

private Background(int shape_type, Shape shape, int fill_color, int stroke_color, int stroke_width) {
    super(shape);
    this.shape_type = shape_type;
    this.stroke_width = stroke_width;

    //set the fill_paint
    fill_paint = new Paint(getPaint());
    fill_paint.setColor(fill_color);
    stroke_paint = new Paint(fill_paint);

    //set the stroke paint
    stroke_paint.setStyle(Paint.Style.STROKE);
    stroke_paint.setAntiAlias(false);
    stroke_paint.setStrokeWidth(stroke_width);
    stroke_paint.setColor(stroke_color);
}

@Override   
protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
    switch(shape_type) {
    case UNDERLINE:
        final RectF underline = new RectF(getBounds().left - stroke_width, getBounds().top - stroke_width, 
                getBounds().right + stroke_width,
                getBounds().bottom - stroke_width);

        canvas.drawRect(underline, stroke_paint);
        break;
    case RECTANGLE:
        final RectF rectangle = new RectF(stroke_width, stroke_width, getBounds().right - stroke_width,
                getBounds().bottom - stroke_width);

        canvas.drawRect(rectangle, fill_paint);
        canvas.drawRect(rectangle, stroke_paint);
        break;
    }
}

} }

Then you can just save the drawable created and use it on multiple layouts in code. 然后,您可以保存创建的可绘制对象,并在代码中的多个布局上使用它。

//untested code
Layout layout = (RelativeLayout)findViewById(R.id.your_layout_id);
Background background = Background.newInstance(Background.RECTANGLE, Color.GRAY, Color.BLUE, 1);
layout.setBackground(background);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM