2017-08-11 109 views
0

TL; DR:使用上一个TextView简单android:drawableLeft功能导致崩溃图片旁边的图片?

TextView是Android的最基本的视觉元素之一。那为什么它最基本的功能不起作用?

https://developer.android.com/reference/android/widget/TextView.html#attr_android:drawableLeft

我的代码很简单,它是使用图像的自定义对话框旁边TextView

<TextView 
     android:text="Text next to check mark" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"   
     android:id="@+id/textView19" 
     android:drawableLeft="@drawable/ic_check_circle_white_24dp" 
     android:textSize="24sp" 
     android:textStyle="normal|bold"/> 

的代码提供了可视化编辑器惊人的结果:

enter image description here

但是当程序实际上是ex ecuted,简单android:drawableLeft功能崩溃的应用程序:

android.view.InflateException: Binary XML file line #64: Error inflating class TextView 

Full stacktrace


我尝试打开该对话框,如下所示:

dialog = new Dialog(this,R.style.Theme_AppCompat_Light_Dialog_Alert); 
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
dialog.setContentView(R.layout.premium_dialog); 
dialog.setCanceledOnTouchOutside(false); 

dialog.getWindow().setLayout((int) (getResources().getDisplayMetrics().widthPixels * 0.90), (int) (getResources().getDisplayMetrics().heightPixels * 0.90)); 

dialog.show(); 

为什么说这样的基本功能InflateException的原因? (我知道这是导致该问题的drawableLeft函数,因为当我删除TextView时,错误消失)

+0

从完整的堆栈跟踪在那里你用'造成的:android.content.res.Resources $ NotFoundException:文件** RES /绘制/ abc_dialog_material_background.xml **从颜色状态列表资源ID#0x7f020011' –

+0

不能在较低API的'Textview'中直接使用'vectordrwable'。创建CustomTextview以支持向下API中的向量 –

回答

3

尝试这一项上的setContentView

LayoutInflater layoutInflater = LayoutInflater.from(context); 
View promptView = layoutInflater.inflate(R.layout.premium_dialog, null); 
dialog.setContentView(promptView); 
+0

下载了复选标记。为什么这个工作? –

1

android:drawableLeft(和顶部/右/底部)不能在较旧的API级别上使用矢量绘制。可以使用.png drawable,或者在TextView旁边使用带有ImageView的LinearLayout。

+0

这是一个PNG,我从https://material.io/icons/#ic_check_circle –

3

创建下的API VectorDrawable一个CustomTextView。

用来初始化您的自定义的TextView的属性如下:

private void initAttrs(Context context, AttributeSet attrs) { 
     if (attrs != null) { 
      TypedArray attributeArray = context.obtainStyledAttributes(attrs,R.styleable.CustomTextView); 
      //for font 
      String fontName = attributeArray.getString(R.styleable.CustomTextView_font); 

      try { 
       if (fontName != null) { 
        Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontName); 
        setTypeface(myTypeface); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

      Drawable drawableLeft = null; 
      Drawable drawableRight = null; 
      Drawable drawableBottom = null; 
      Drawable drawableTop = null; 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
       drawableLeft = attributeArray.getDrawable(R.styleable.CustomTextView_drawableLeftCompat); 
       drawableRight = attributeArray.getDrawable(R.styleable.CustomTextView_drawableRightCompat); 
       drawableBottom = attributeArray.getDrawable(R.styleable.CustomTextView_drawableBottomCompat); 
       drawableTop = attributeArray.getDrawable(R.styleable.CustomTextView_drawableTopCompat); 
      } else { 
       final int drawableLeftId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableLeftCompat, -1); 
       final int drawableRightId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableRightCompat, -1); 
       final int drawableBottomId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableBottomCompat, -1); 
       final int drawableTopId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableTopCompat, -1); 

       if (drawableLeftId != -1) 
        drawableLeft = AppCompatResources.getDrawable(context, drawableLeftId); 
       if (drawableRightId != -1) 
        drawableRight = AppCompatResources.getDrawable(context, drawableRightId); 
       if (drawableBottomId != -1) 
        drawableBottom = AppCompatResources.getDrawable(context, drawableBottomId); 
       if (drawableTopId != -1) 
        drawableTop = AppCompatResources.getDrawable(context, drawableTopId); 
      } 
      setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom); 
      attributeArray.recycle(); 
     } 
    } 

您的自定义设置样式为相同。

<attr name="drawableLeftCompat" format="reference" /> 
    <attr name="drawableRightCompat" format="reference" /> 
    <attr name="drawableTopCompat" format="reference" /> 
    <attr name="drawableBottomCompat" format="reference" /> 

    <declare-styleable name="CustomTextView"> 
     <attr name="font" format="string" /> 
     <attr name="drawableLeftCompat" /> 
     <attr name="drawableRightCompat" /> 
     <attr name="drawableTopCompat" /> 
     <attr name="drawableBottomCompat" /> 
    </declare-styleable> 
+0

为什么?我只是从(https://material.io/icons/#ic_check_circle)处理简单的.png,而不是向量!为什么我必须实现这个方法,如果基本功能是使用'drawableLeft'? –

+0

@Ruchir Banronia如果你的'drawableLeft'不是Vector _(哪个更具优势和可伸缩性)_,则不需要创建自定义Textview来访问.png文件。但是从你的stackTrace来看,它表明你正试图访问矢量绘图。 –

+0

这就是为什么我很困惑。我从这里使用.png文件:https://material.io/icons/#ic_check_circle。还有其他建议吗? –