2017-08-10 42 views
0

我想制作一个包含进度视图和按钮的视图。通过视图的XML,我想添加定义按钮和porgress栏样式的字段。使用风格

我到目前为止已经完成,但它不工作:

<io.**.**.view.ButtonLoading android:id="@+id/b_recover_password" 
             android:layout_width="wrap_content" 
             android:gravity="center" 
             app:styleButton="@style/ButtonGrey" 
             app:styleProgress="@style/ProgressBar" 
             app:textButton="@string/recover_password" 
             android:layout_height="wrap_content"/> 

代码:

a = context.getTheme().obtainStyledAttributes(
      attrs, 
      R.styleable.ButtonLoading, 
      0, 0); 

    int buttonId = 0;// R.style.Widget_AppCompat_Button; 
    try { 
     buttonId = a.getResourceId(R.styleable.ButtonLoading_styleButton, 0); 
    } catch (Exception e) { 
    } 

    button = new Button(getContext(), attrs, buttonId); 

    LayoutParams lpButton = createLayoutParams(); 
    button.setLayoutParams(lpButton); 
    color = button.getCurrentTextColor(); 

    int progressId = 0;// R.style.Widget_AppCompat_ProgressBar; 
    try { 
     progressId = a.getResourceId(R.styleable.ButtonLoading_styleProgress, 0); 
    } catch (Exception e) { 
    } 

    progressBar = new ProgressBar(getContext(), attrs, progressId); 
    LayoutParams lpProgressBar = createLayoutParams(); 
    lpProgressBar.addRule(RelativeLayout.CENTER_IN_PARENT); 
    progressBar.setLayoutParams(lpProgressBar); 

    LayoutParams lpRelativeLayout = createLayoutParams(); 
    setLayoutParams(lpRelativeLayout); 

    addView(button); 
    addView(progressBar); 

    try { 
     String value = a.getString(R.styleable.ButtonLoading_textButton); 
     button.setText(value); 
    } catch (Exception e) { 
    } 
    a.recycle(); 

设置样式:

<declare-styleable name="ButtonLoading"> 
    <attr name="styleButton" format="reference" /> 
    <attr name="styleProgress" format="reference" /> 
    <attr name="textButton" format="string" /> 
</declare-styleable> 

有人帮帮我吗?谢谢

+0

当你说“它不工作”,这到底意味着什么? – Cheticamp

+0

按钮和进度条上的样式集不起作用。坚持默认风格。 –

+0

此代码位于自定义视图中。在这个观点里面有什么方法。什么是基础(扩展)视图。你可以发布你的进度条和按钮的样式吗? – Cheticamp

回答

1

问题是在您的构造函数中为ButtonProgressBar。让我们考虑两个构造函数。 (重点是我的。)(Documentation

视图(上下文的背景下,的AttributeSet ATTRS,INT defStyleAttr)[适合以下API 21]

从XML执行通货膨胀和应用特定类基本风格从主题属性。 View的这个构造函数允许子类在膨胀时使用他们自己的基础样式。例如,一个Button类的构造函数会调用这个版本的超类构造函数,并为defStyleAttr提供R.attr.buttonStyle;这允许主题的按钮样式修改所有基本视图属性(特别是其背景)以及Button类的属性。

视图(上下文的背景下,的AttributeSet ATTRS,INT defStyleAttr,INT defStyleRes)[适合API 21+]

从XML执行通货膨胀和从一个主题属性或样式应用类特定的基本样式资源。 View的这个构造函数允许子类在膨胀时使用他们自己的基础样式。

关注最后两个参数。

defStyleAttr int:当前主题中的一个属性,它包含对为视图提供默认值的样式资源的引用。可以为0以不寻找默认值。

defStyleRes int:为视图提供默认值的样式资源的资源标识符,仅当defStyleAttr为0或无法在主题中找到时使用。可以为0以不寻找默认值。

这是令人困惑的,因为有资源ID指向资源ID,但忍受着我。

您为buttonIdprogressId定义的内容是一个指向样式(<style...)的资源ID。如上所述,此样式资源ID适用于ButtonProgressBar构造函数的defStyleRes属性。您正尝试将这些资源值中的每一个用作指向当前主题中某个属性的标识。换句话说,你在说,R.attr.styleButton(styleButton)是当前主题中的一个属性,它不像当前定义的那样。为了解决这个问题,主题样式更改为以下:

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 
    <item name="styleButton">@style/ButtonGrey</item> 
    ... 
</style>   

为了让你有API工作21+,你可以离开留下的样式和布局文件,因为它们并将自定义视图代码更改为以下内容。 (我只显示按钮的代码,但进度条会类似)。您可能需要为API 21+(styles-v21.xml)创建单独的样式文件。

public CustomViewGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    TypedArray a = context.getTheme().obtainStyledAttributes(
      attrs, 
      R.styleable.ButtonLoading, 
      0, 0); 
    int defStyleRes = 0; 
    try { 
     defStyleRes = a.getResourceId(R.styleable.ButtonLoading_styleButton, 0); 
    } catch (Exception e) { 
     // do something 
    } 
    Button button; 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     // defStyleRes is only used if defStyleAttr == 0 
     // or can't be found in the current theme. 
     button = new Button(getContext(), attrs, defStyleAttr, defStyleRes); 
    } else { 
     button = new Button(getContext(), attrs, 
        (defStyleAttr != 0) ? defStyleAttr : R.attr.styleButton); 
    } 
    try { 
     String value = a.getString(R.styleable.ButtonLoading_textButton); 
     button.setText(value); 
    } catch (Exception e) { 
     // do something 
    } 
    addView(button); 
    a.recycle(); 
} 

设置按钮的文本按照您的编码进行。样式更棘手。为了让app:styleButton="@style/ButtonGrey"按照您打算用于所有API的方式工作,我认为您必须执行类似this之类的操作。

我希望这会有所帮助。

0

我的风格是:

<!-- Base application theme. --> 
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 
    <!-- Customize your theme here. --> 
    <item name="colorPrimary">@color/colorPrimary</item> 
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item> 
    <item name="colorAccent">@color/colorAccent</item> 
    <item name="android:buttonStyle">@style/ButtonAppTheme</item> 
    <item name="android:progressBarStyle">@style/ProgressBarBase</item> 
</style> 

<style name="ProgressBarBase" parent="android:Widget.Holo.Light.ProgressBar"> 
    <item name="android:textColorTertiary">@color/color_grey</item> 
</style> 

<style name="ProgressBar" parent="android:Widget.Holo.Light.ProgressBar"> 
    <item name="android:textColorTertiary">@color/color_black</item> 
</style> 

的问题是,你总是有 “ProgressBarBase” 的风格。也就是说,它不是压倒一切的。