动态给TextView控件设置权重

2016-10-16 17:44 阅读 5,516 次 评论 0 条
版权声明:本文著作权归TeachCourse所有,未经许可禁止转载,谢谢支持!
转载请注明出处:http://teachcourse.cn/2059.html

摘要:

如何给TextView控件动态设置权重?权重属于LinearLayout布局子控件的一个属性,想要动态添加一个TextView控件的权重,调用setLayoutParams()方法,传入LinearLayout.LayoutParams对象,并在LinearLayout.LayoutParams构造方法中指定控件的宽,高和权重。

  1. LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);    
  2.          TextView tv=new TextView(this);  
  3.          tv.setLayoutParams(lp);  

关于TextView动态添加到LinearLayout父控件中出现“The specified child already has a parent”异常,动态设置setCompoundDrawables(drawable, null, null, null)没有效果和TextView的android:textColor属性添加颜色选择器没有改变颜色。

一.The specified child already has a parent异常

这句话的意思“当前子控件已经拥有一个父控件”,言外之意:一个子控件只允许有一个父控件,这就像现实生活:一个儿子有且仅有一个亲爸,出现这种异常的两个原因:一是拥有父控件的子控件被添加到另一个父控件中;二是同一个子控件被重复添加到一个父控件中

第一种提示:“The specified child already has a parent”的原因演示,设置布局文件activity_text_view

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:id="@+id/activity_text_view"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent"  
  7.     android:gravity="center"  
  8.     tools:context="com.sinolvc.zspg.view.TextViewActivity">  
  9.   
  10.     <TextView  
  11.         android:id="@+id/child_widget_tv"  
  12.         android:layout_width="wrap_content"  
  13.         android:text="子控件"  
  14.         android:textSize="@dimen/dp_018"  
  15.         android:layout_height="wrap_content" />  
  16. </LinearLayout>  

在MainActivity中使用LayoutInflater来解析布局文件activity_text_view,然后调用setContentView()方法,将布局初始化后的View添加到窗体中

  1. LinearLayout ll=(LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_text_view,null);   
  2.        setContentView(ll);  

上述代码实现的效果和直接调用setContentView(R.layout.activity_text_view)一样,然后可以正常运行,没有报“The specified child already has a parent”的异常。这个时候,如果获取到LinearLayout父控件内的TextView子控件,最后调用setContentView()方法,即

  1. TextView tv=(TextView) ll.findViewById(R.id.child_widget_tv);  
  2.         setContentView(tv);  

运行异常,Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

001-the-specified-child-already-has-a-parent

调用父控件的removeView()方法“断绝父子关系”,之后才能添加被另一个父控件中,然后运行不再报错,即

  1. LinearLayout ll=(LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_text_view,null);  
  2.        TextView tv= (TextView) ll.findViewById(R.id.child_widget_tv);  
  3.        ll.removeView(tv);  
  4.        setContentView(tv);  

第二种提示:“The specified child already has a parent”原因演示,设置布局文件activity_text_view_second

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:id="@+id/activity_text_view"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent"  
  7.     android:gravity="center"  
  8.     tools:context="com.sinolvc.zspg.view.TextViewActivity">  
  9.   
  10. </LinearLayout>  

在MainActivity类中动态添加多个TextView控件,设置TextView的图标和颜色选择,然后添加到父控件LinearLayout中,正确的做法即

  1. LinearLayout ll=(LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_text_view,null);  
  2. TextView tv=null;  
  3. LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f)  
  4.         for(int i=0;i<3;i++){  
  5.             tv=new TextView(this);  
  6.             tv.setLayoutParams(lp);  
  7.             tv.setText("子控件:"+i);  
  8.             ll.addView(tv);  
  9.         }  
  10. setContentView(ll);  

报异常的原因:同一个TextView对象被重复添加到LinearLayout父控件中(解析一个布局文件时需要注意)如下

  1. LinearLayout ll=(LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_text_view,null);  
  2. TextView tv=new TextView(this);  
  3. LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f)  
  4.         for(int i=0;i<3;i++){            
  5.             tv.setLayoutParams(lp);  
  6.             tv.setText("子控件:"+i);  
  7.             ll.addView(tv);  
  8.         }  
  9. setContentView(ll);  

二.动态设置setCompoundDrawables(drawable, null, null, null)没有效果

TextView可以在其左边、上边、右边和下边添加Drawable对象,开发可以调用setCompoundDrawables(drawable,null,null,null)添加,在获取drawable对象后,还需要设置drawable的setBound()方法设置限制,否则没有效果,即

  1. Drawable drawable=getResources().getDrawable(R.drawable.ic_launcher);  
  2.          drawable.setBounds(00, drawable.getMinimumWidth(),drawable.getMinimumHeight());  
  3.   
  4.          tv.setCompoundDrawables(drawable,null,null,null);  

也可以调用setCompoundDrawablesWithIntrinsicBounds(int,int,int,int)或setCompoundDrawablesWithIntrinsicBounds(Drawable, Drawable, Drawable, Drawable)方法,,不需要设置Drawable的setBound()方法。

  1. tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_launcher,0,0,0);  

或者

  1. Drawable drawable=getResources().getDrawable(R.drawable.ic_launcher);  
  2.          tv.setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null);  

PS:需要注意区别setCompoundDrawablesRelativeWithIntrinsicBounds(int,int,int,int)和setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable,Drawable,Drawable,Drawable)

三.TextView的android:textColor属性添加颜色选择器没有改变颜色

选择器分为:color和drawable,在res文件夹下手动创建color或drawable文件夹,然后存放selector根标签声明的item文件,系统会根据View当前的状态从selector中选择对应的item,每个item对应着一个具体的Drawable,系统按照从上到下的顺序查找,直到查找到第一条匹配的item。一般来说,默认的item都应该放在selector的最后一条并且不附带任何的状态,这样当上面的item都无法匹配View的当前状态时,系统就会选择默认的item(上述文字来源《Android开发艺术探索》)。

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:color="@android:color/holo_blue_dark" android:state_selected="true"/>  
  4.     <item android:color="@android:color/holo_purple" android:state_focused="true"/>  
  5.     <item android:color="@android:color/holo_red_dark" android:state_checkable="true"/>  
  6.     <item android:color="@android:color/holo_red_light" android:state_enabled="true"/>  
  7.     <item android:color="@android:color/holo_blue_bright" android:state_single="true"/>  
  8.     <item android:color="@android:color/holo_green_light" android:state_activated="true"/>  
  9.     <item android:color="@android:color/holo_green_dark" android:state_accelerated="true"/>  
  10.     <item android:color="@android:color/holo_orange_light" android:state_pressed="true"/>  
  11.     <item android:color="@android:color/holo_orange_dark" android:state_window_focused="true"/>  
  12.     <item android:color="@android:color/black"/>  
  13. </selector>  

在TextView的android:textColor属性中,可以将上面代码(text_view_color_selector.xml)存放在color或drawable文件夹下,经过测试都可以正常引用,即

  1. android:textColor="@color/text_view_color_selector"  

或者

  1. android:textColor="@drawable/text_view_color_selector"  

默认情况下,TextView无法获取点击事件,即android:clickable="false",如果在xml文件设置了android:onClick=""属性,必须设置clickable为非false。如果TextView调用setOnClickListener()方法,同样会先判断clickable是否为非false,否则设置为true,这一步在源码执行,不需要手动设置。TextView源码提供setTextIsSelectable()方法获取焦点状态,setSelected()方法设置当前View是否选择状态,在同时调用上述两个方法时,根据color或drawable选择器item状态的先后顺序,优先改变android:textColor属性的颜色,调用了其中一种item状态就不会在执行另一种状态,所有状态都不符合才会调用最后的item。这就是为什么TextView在添加了上述选择/选中/按下等状态没有效果的原因。

关注公众号 扫一扫二维码,加我QQ

如果文章对你有帮助,欢迎点击上方按钮关注作者

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ1589359239或公众号TeachCourse)
转载请注明出处:http://teachcourse.cn/2059.html
分类:Android 标签:, ,
Android开发之TextView控件设置颜色切换器的问题 Android开发之TextView控件设
第一次使用Android Studio的感受 第一次使用Android Studio的感
关于刘翔妈妈我听闻的一件事,绝对不是个好伺候的婆婆 关于刘翔妈妈我听闻的一件事,绝
Android开发之深入理解泛型extends和super的区别 Android开发之深入理解泛型exte

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情