在Activity之外调用findViewById返回null

时间:2014-09-30 12:06:11

标签: android

为了在运行时动态显示加载视图,我创建了一个self_pro_bar.xml并创建了一个普通的java类ShyProgressBar。将自定义视图附加到代码中的主视图中,然后,如果在Activity类中调用findViewById,它可以找到添加的自定义视图,但是它从普通的java类调用findViewById,它总是返回null。

self_pro_bar.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/selfprogressbar"
    android:gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:layout_width="100dp"
    android:layout_height="30dp"
    android:orientation="horizontal" 
    android:background="#eee">

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="loading..."
        />

</LinearLayout>

ShyProgressBar类

public class ShyProgressBar {
        private Context context;
        public ShyProgressBar(Context context) {
            this.context = context;
        }

        public View get() {
            LayoutInflater inflater = (LayoutInflater) 
                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            return inflater.inflate(R.layout.self_pro_bar, null);
        }

        public boolean exist(Activity activity) {
            return activity.findViewById(R.layout.self_pro_bar) != null;
        }
 }

主要活动xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="load_data"
        android:text="@string/click_me" />

    <LinearLayout
        android:id="@+id/dataview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

主要活动

    public class MainActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
        public void load_data(View v) {
            ShyProgressBar ins = new ShyProgressBar(this);
            View p_b = ins.get();
            if(!ins.exist(MainActivity.this)) {
                LinearLayout rl = (LinearLayout) findViewById(R.id.dataview);
                rl.addView(p_b);
                Object c = ins.exist(MainActivity.this) // this code still returns null!
            }
        }
}
  1. 不起作用 - 在ShyProgressBar中调用findViewById时,对象c值仍为null。
  2. 如果在下面的语句中使用,则判断视图是否存在于Activity类的load_data方法中。 查看p_b_v = findViewById(R.id.selfprogressbar);它工作正常,值不为空。
  3. 不确定为什么findViewById在Activity中有效,但在非活动类中无效。

3 个答案:

答案 0 :(得分:1)

您的存在方法不正确。在那里,您再次膨胀Main_activity.xml,然后检查是否存在R.layout.self_pro_bar。它当然不存在,因为此项不是Main_activity布局的一部分。完成此项检查后,您将丢弃刚刚充气的布局 - 您不会将其附加到任何地方。

不需要方法“存在”,而是在您的活动代码中,您可以检查self_pro_bar是否已使用以下代码添加到主布局:

public void load_data(View v) {
    ShyProgressBar ins = new ShyProgressBar(this);
    if(findViewById(R.id.selfprogressbar) == null) {
       LinearLayout rl = (LinearLayout) findViewById(R.id.dataview);
       View p_b = ins.get();
       rl.addView(p_b);
       }
    }

答案 1 :(得分:0)

因为findViewById(R.id.dataview)是Activity类的方法。

当你使用Activity扩展你的课程时会出现。 如果你想在非活动类中使用方法参数,你可以传递它。 例如: -

void methodName(Activity activity){
}

并且在通过时使用YourActivity.this

答案 2 :(得分:0)

您不能在findViewById之外使用Activity方法,但如果您想使用TextViewButton或在活动oncreate中声明的任何内容,将其设置为静态方法。从该静态方法调用组件。

<强>更新 第1步:

活动onCreate方法()

Button b= (Button) findViewById(R.id.yourComponentID);

第2步:

创建一个类:

public class xyz{
Button x ;
public static void save_Button(Button b){
x = b;
}
public static Button get_button(){
 return x;
}
}

第3步:  在您的活动中调用此save_Button方法 例如

save_Button(b);

第4步:

您可以从应用的任何位置拨打get_button()