findViewById在自定义视图中返回null,其中包含子视图

问题描述:

我正在开发一个视图,它显示了一堆消息,它们使fadeIn,fadeOut和它们之间的等待时间消失。它有一堆消息,当我需要显示其中的一些时,我添加了它。该视图没有特定的设计,因此用户可以像他想要的那样进行自定义。findViewById在自定义视图中返回null,其中包含子视图

我已经写好了3个超级构造函数。

的XML布局是下一个:

[... Others views ...] 

    <com.example.lectorrss.Views.StatusMessage 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/statusMessage" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="50dp" 
      android:layout_alignParentBottom="true" 
      android:background="#6894ed"> 

      <ProgressBar 
       android:id="@+id/progressBar" 
       android:layout_centerVertical="true" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" /> 

      <TextView 
       android:id="@+id/message" 
       android:layout_toRightOf="@id/progressBar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_centerVertical="true" 
       android:text="Hola" 
       android:textColor="#fff"></TextView> 

      </RelativeLayout> 

     </com.example.lectorrss.Views.StatusMessage> 


[... Other views ...] 

在这种情况下,我想我的自定义视图显示在里面(进度条+ TextView的),然后申请我想要的行为的看法。

我CustomView的代码是:

public class StatusMessage extends ViewGroup{ 

    private List<String> messagesStack; 
    private Worker worker; 

    public StatusMessage(Context context) { 
     super(context); 
    } 

    public StatusMessage(Context context, AttributeSet attrs){ 
     super(context, attrs); 

    } 

    public StatusMessage(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 


    @Override 
    protected void onAttachedToWindow() { 

     super.onAttachedToWindow(); 

     TextView txtView = (TextView) this.findViewById(R.id.message); 
     if(txtView == null){ 
      Log.d("BrowsePortal", "TextView null"); 
     }else{ 
      // HERE, THE CODE CAN FIND OK THE VIEW I WANT 
      Log.d("BrowsePortal", "TextView not null"); 
     } 

     worker = new Worker(this); 
     worker.execute(); 

    } 

    [Other logic code about view] 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 

    } 

} 

但是作为我的观点需要消息之间等待的时间,并使用动画,我需要创建的AsyncTask:

public class Worker extends AsyncTask<Void,String,Void>{ 

    private StatusMessage view; 

    public Worker(StatusMessage view) { 
     this.view = view; 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     [I supressed all logic code here] 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     TextView txtView = (TextView) view.findViewById(R.id.message); 
     if(txtView == null){ 
      // But here the code return null 
      Log.d("BrowsePortal", "TextView null"); 
     }else{ 
      Log.d("BrowsePortal", "TextView not null"); 
     } 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
     [I supressed all logic code here] 
    } 
} 

我的问题是从asynctask,progressUpdate,当我需要访问textview时,findviewbyid返回null。但试图从自定义视图类访问相同的视图,而不是asynctask,它的工作原理。为什么从视图类我可以访问textview,但从asynctask不是?

此外,在后执行,相同的代码返回空。

我的asynctask在她的构造函数中获得了很好的效果,因此从这里开始的视图将会像customview一样运行良好。

+0

什么样的代码被“[关于视图的其他逻辑代码]”遮蔽?您是否在应用程序生命周期的任何时候删除了该视图? – Knossos 2014-09-25 12:50:06

+0

@Knossos'[关于视图的其他逻辑代码]'是与'StatusMessage.stackMessages'属性相关的代码。像'addMessageToStack()','getNextMessageFromStack()','areThereMessages()'......方法是不重要的,但我为此压制了它。他们也不以观点操作。另一方面,在'Worker'类中,隐藏的代码与动画,等待时间等有关......我认为动画代码可能会做一些错误的事情,但几分钟前,删除所有的AsyncTask只能与如果检查TextView,但仍然工作不正常。 – korima 2014-09-25 13:25:50

+0

我很困惑,我必须说。如果在onAttachedToWindow()中获得“TextView not null”,并在AsyncTask中获得“TextView null”。你可以尝试两个测试吗? 1.创建一个成员变量TextView,并使用构造函数中的View实例化它。从onProgressUpdate中删除实例化代码。作品? 2.将TextView本身传入AsyncTask,将其设置为成员变量,并在onProgressUpdate()中测试其完整性。 – Knossos 2014-09-25 13:33:03

的问题是这一行:

import android.R我改变import [app_package].R;

然后,当我把这个行:

TextView txtView = (TextView) view.findViewById(R.id.message);

...因为使用作为识别码,从android.R而不是package.R资源的方法找不到TextView的。

最奇怪的是,在我之前做的活动中,有时我做了同样的错误,但我可以快速修复,因为Eclipse说我指定的资源没有找到资源行的底线,但由于某种原因,在这种情况下没有通知我。也许R.id.message保留给android.R。

+0

确保您尽快接受您自己的答案,以便其他人知道问题所在。 – Knossos 2014-09-26 04:45:50