如何在背景drawable的笔划改变后正确布局视图?

时间:2016-01-06 22:24:48

标签: android android-layout

我有什么:

我有一个LinearLayout,其中包含Views,背景为Drawable(带圆角和笔划的矩形)。它们充当颜色选择按钮。最初,第一个按钮的背景较粗(4px而不是1px)。一切都很好(见下图左侧)。

我想要的是什么:

然而,当我按下这样一个按钮时,我想从之前选择的按钮中移除粗线条并将其应用到实际按钮。我尝试以下方式(只是一个片段):

// get layout
LinearLayout favoriteColorsLayout = (LinearLayout) findViewById(R.id.favoriteColorsLayout);

// get view at old position, update stroke, invalidate
View view = favoriteColorsLayout.getChildAt(selectedColorButton);
GradientDrawable drawable = (GradientDrawable) view.getBackground();
drawable.setStroke(1, Color.parseColor("#bbbbbb"));
view.invalidate(); // do I need this?

// also update stroke of new view
..

// re-layout
favoriteColorsLayout.requestLayout(); // do I need this?

我看到的内容:

事实上,较粗的笔划被移动但不幸的是之后的布局是错误的!按钮2-4的彩色背景应该变得更薄,当它们周围的笔划变得更厚时,它们仍然适合包含的布局,但这不会发生(见下图右侧)。相反,笔划被部分切断(因为否则它将被绘制在视图的边界之外)。这不是预期的效果。

我需要做些什么来取得理想的效果? 我知道我在运行时只有多少颜色的按钮,所以我更喜欢程序化解决方案。

实际上,我开始认为它可能是一个Android错误,因为默认情况下在边框外绘制笔划肯定不是理想的行为。我看到了模拟器和API级别23的影响,以及API等级为11的旧手机。

enter image description here

一点布局xml。线性布局(视图以编程方式添加):

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:id="@+id/favoriteColorsLayout"></LinearLayout>

按钮视图:

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/color_selection_button_size"
    android:layout_height="@dimen/color_selection_button_size"
    android:layout_margin="@dimen/color_selection_button_margin"
    android:layout_gravity="center"
    android:background="@drawable/color_selection_cell_background">
</View>

按钮background drawable(color_selection_cell_background.xml):

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

    <stroke
        android:width="1px"
        android:color="#bbbbbb"/>

    <corners
        android:radius="5px" />

    <gradient
        android:angle="90"
        android:centerX="0.5"
        android:centerY="0.5"
        android:startColor="#aaaaaa"
        android:endColor="#bbbbbb"
        android:type="linear" />
</shape>

1 个答案:

答案 0 :(得分:2)

不确定为什么要在代码中执行此操作,但为什么不使用两个drawable并更改它们?

<强> button_blue_selected.xml:

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

    <solid android:color="@color/blue_500" />
    <stroke android:width="4dp" android:color="@color/grey_500" />
    <corners android:radius="5dp" />
</shape>

<强> button_blue_unselected.xml:

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

    <solid android:color="@color/blue_500" />
    <stroke android:width="1dp" android:color="@color/grey_500" />
    <corners android:radius="5dp" />
</shape>

然后更新代码中的背景:

View view = favoriteColorsLayout.getChildAt(selectedColorButton);
view.setBackgroundResource(R.drawable.button_blue_selected);

甚至更好的是你可以使用第三个drawable with state,所以你不需要直接在代码中更新它:

<强> button_blue.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/button_blue_selected" />
    <item android:drawable="@drawable/button_blue_unselected" />
</selector>

然后:

view.setSelected(true);