SetContentView и findViewById

После прочтения некоторых связанных должностей я уже знаю, что я должен явно вызвать setContenView, прежде чем пытаться найти по id элемент в иерархии Activity-View-Hierarchy. Я создал Activity с раздутым представлением, и все работает отлично. Проблема в том, что когда я пытаюсь установить другое представление для этого действия, используя следующий 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. Что я делаю не так?

Спасибо

Solutions Collecting From Web of "SetContentView и findViewById"

Вы можете попробовать LayoutInflater.

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

Счастливые кодировки

Вы уверены, что btn и bnt одинаковы?

Я бы предложил использовать фрагменты Google dev Fragments

Однако, если вы хотите сделать это так, дайте вашему «внешнему» макету в main_activity.xml определенный идентификатор, скажем 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); } 

Чтобы использовать фрагменты, создайте класс, реализующий фрагмент для каждого вида просмотра, который может иметь ваша активность. Ваша 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); } } 

Вы должны подождать окончания замены. Попробуй это:

 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); 

Вы можете попробовать это, в вашем 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); } 

К сожалению, я не знал, что id my_bnt существует, но только в одном из существующих макетов (не в макете или в макете-xlarge). Thx для вашей помощи

 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 }