setContentView和findViewById

时间:2015-10-08 05:42:03

标签: android

在阅读了一些相关帖子后,我已经知道在尝试通过id将一个元素发现到Activity-View-Hierarchy之前,我必须显式调用setContenView。我创建了一个带有膨胀视图的活动,一切正常。问题是当我尝试使用下一个xml和代码设置此活动的另一个视图时:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:background="#B12A6D"
tools:context=".MainActivity"
android:orientation="vertical"
>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="top"
    android:background="@drawable/bg_purple_500"
    android:layout_margin="0dp"
    >

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/GridLayout1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="50"
        android:columnCount="4"
        android:rowCount="4"
        android:orientation="horizontal"
        tools:context=".GridXMLActivity"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        >

         <ImageView
            android:id="@+id/my_bnt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/icon_new_game"
            android:contentDescription="@string/text"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginBottom="10dp"
            />
</GridLayout>

</LinearLayout>

</RelativeLayout>

代码:

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

}


....

protected void method_triggered_from_UI_thread() {

  // Inflate other layout...
  View view = View.inflate(this, R.layout.my_layout, null) ;
  setContentView(view);
  ImageView btn = (ImageView) findViewById(R.id.my_bnt);
  // btn is null...

}

我尝试过其他轻微变化:

View mainView = findViewById(android.R.id.content);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.my_layout, (ViewGroup) mainView, false)  ;
setContentView(view);
ImageView btn = (ImageView) view.findViewById(R.id.my_bnt);

我总是得到btn == null。我做错了什么?

THX

6 个答案:

答案 0 :(得分:2)

您可以尝试使用LayoutInflater。

View inflatedView = LayoutoutInflater.from(context).inflate(R.layout, null);
setContentView(inflatedView);

快乐编码

答案 1 :(得分:0)

你确定btn和bnt是一样的吗?

我建议使用片段Google dev Fragments

但是,如果您想这样做,请提供您的外部&#39; main_activity.xml中的布局是一个特定的id,比如rootView。然后打电话给:

protected void methodTriggeredFromUiThread(){
    LinearLayout rootView = findViewById(R.id.rootView);
    View view = View.inflate(this, R.layout.my_layout, null) ;
    rootView.removeAllViews();
    rootView.addView(view);
    view.findViewById(R.id.my_bnt); 
}

要使用片段,请为您的活动可能具有的每种类型的视图创建一个实现Fragment的类。你的main_activity只会持有一个FrameLayout(除了持久标题,标签,等等)。由于按钮是一个视图,它位于主活动内部的片段内,只要片段被加载,主活动中任何地方调用findViewById(R.id.btn)都会产生按钮。

在activity_main.xml中的某个地方:

 <FrameLayout
        android:id="@+id/fragmentHolder"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
  </FrameLayout>

<强> MainActivity.java

public class MainActivity extends Activity {
    private FragmentManager mFragmentManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loadFragment(new DemoFragment());
    }
    protected void loadFragment(Fragment fragmentToLoad) {
        FragmentTransaction fragmentTransaction = mFragmentManager
            .beginTransaction();
        fragmentTransaction.replace(R.id.fragmentHolder, fragmentToLoad);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
    }
}

<强> DemoFragment.java

public class DemoFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.my_layout,
                container, false);
    }
}

答案 2 :(得分:0)

您必须等待更换结束。试试这个:

View view = View.inflate(this, R.layout.my_layout, null);
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {          
     @Override          
     public void onGlobalLayout() {              
        // continue the initialization from here:
        btn = (ImageView) view.findViewById(R.id.my_bnt);
        //...

        view.getViewTreeObserver().removeGlobalOnLayoutListener(this);        
     }      
}); 
setContentView(view);

答案 3 :(得分:0)

你可以试试这个,在 R.layout.activity_main中添加一些ViewGroup (FrameLayout),然后在method_triggered_from_UI_thread()中添加膨胀的视图到该容器:

protected void method_triggered_from_UI_thread() {

// Inflate other layout...
  View view = View.inflate(this, R.layout.my_layout, null);

// add new view to the container view in activity layout
 (ViewGroup) findViewById(R.id.container).addView(view);

ImageView btn = (ImageView) findViewById(R.id.my_bnt);

}

答案 4 :(得分:0)

抱歉,我没有意识到id存在my_bnt,但仅存在于一个现有布局中(不在layout-land或layout-xlarge中)。 谢谢你的帮助

答案 5 :(得分:-2)

You can't assign a view,and do findviewbyid to an activity outside oncreate, an it just won't work. 
you need to rearrange your code in 
//declare image as global variable
ImageView btn;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
   Bundle extraArgs = getIntent().getExtras();
String layoutname=extraArgs.get("LayoutName");
if(layoutname="main")
    setContentView(R.layout.activity_main);
else 

  setContentView(R.layout.my_layout);
  btn = (ImageView) findViewById(R.id.my_bnt);

}



protected void method_triggered_from_UI_thread()
{
//Call the main activity again with bundle giving view 
Intent intent = new Intent();
intent.setClass(this, MainActivity.class);
intent.putExtra("LayoutName", "UR_LAYOUT_NAME");
startActivity(intent);/// or use startactivityforresult,

//access btn here
}