更改android中的AttributeSet值

时间:2015-10-03 12:29:32

标签: android android-custom-view android-custom-attributes

我有自定义视图,它将属性集(xml值)作为构造函数值

public CustomView(Context context)  // No Attributes in this one.
{
    super(context);
    this(context, null, 0);
}

public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this(context, attrs, 0)
}

public CustomView(Context context, AttributeSet attrs, int default_style) {
    super(context, attrs, default_style);
    readAttrs(context, attrs, defStyle);
    init();
}

在Fragment类中,我将视图设置为

CustomView customView = (CustomView) view.findViewById(R.id.customView); 

其中自定义视图包含各种值,例如高度,宽度,填充等。

我想根据所需条件修改这些值,并将其设置回自定义视图。 我将设置宽度高度代码放在 onDraw 方法中,并调用invalidte视图。 但是如果我在CustomView类中调用 invalidate 方法,则上面的方法将设置每次。 如何克服这一点,以便我只能在构造函数中传递修改后的属性集值。?

编辑:我需要修改在属性构造函数中设置的视图值(使用新值初始化),这样我将获得具有新值的刷新视图。 覆盖@OnDraw或'无效'对于我来说,对于我来说不是一个好的函数,我写了将在每个第二个区间执行的方法。

3 个答案:

答案 0 :(得分:2)

我看到你的CustomView可以有多个属性,你想根据某些条件修改其中的一些属性,并在构造函数中传递它。

设计自定义视图时,几乎没有最佳做法:

  1. 如果您有自定义属性,请确保通过setter和getter公开它们。在您的setter方法中,请致电invalidate();
  2. 请勿尝试修改onDraw()onMeasure()方法中的任何属性。
  3. 尽量避免为自定义视图编写自定义构造函数。
  4. 因此,解决问题的理想方法是实例化CustomView,然后在外部(在Activity或Fragment中)修改属性,或在CustomView.java内部使用方法,然后在外部调用它。这样做仍然会给你你想要的相同结果。

答案 1 :(得分:0)

这可能不是您希望的解决方案,但在您的xml中放置 FrameLayout 而不是 CustomView ,然后创建 CustomView 以编程方式使用 FrameLayout 作为其父

答案 2 :(得分:0)

因此,假设您为名为StarsView的视图声明了这样的自定义属性

<declare-styleable name="StarsView">
    <attr name="stars" format="integer" />
    <attr name="score" format="float" />
</declare-styleable>

你想从这样的东西中读取属性

<my.package..StarsView
    app:stars="5"
    app:score="4.6"

你在构造函数中执行此操作

public StarsView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if(attrs != null) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StarsView, defStyleAttr, 0);
        stars = Tools.MathEx.clamp(1, 10, a.getInt(R.styleable.StarsView_stars, 5));
        score =  (int)Math.floor(a.getFloat(R.styleable.StarsView_score, stars) * 2f);
        a.recycle(); // its important to call recycle after we are done
    }
}