在阅读了一些相关帖子后,我已经知道在尝试通过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
答案 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
}