Java 如何在android中动态设置布局
好吧,假设有一个名为main活动的活动,有两个名为layout1和layout2的布局都有几个按钮。默认情况下,MainActivity布局为layout1,如下所示:Java 如何在android中动态设置布局,java,android,android-layout,android-intent,Java,Android,Android Layout,Android Intent,好吧,假设有一个名为main活动的活动,有两个名为layout1和layout2的布局都有几个按钮。默认情况下,MainActivity布局为layout1,如下所示: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout1); someBtn1.setOnClickListener(new
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutParams default_layout_params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
View view1 = inflater.inflate(R.layout.layout1, null);
addContentView(view1, default_layout_params);
View view2 = inflater.inflate(R.layout.layout2, null);
addContentView(view2, default_layout_params);
view2.setVisibility(View.INVISIBLE);
view1.setVisibility(View.VISIBLE);
view1.bringToFront();
现在我实际做的是单击layout1中的一个按钮,第二个布局设置如下:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutParams default_layout_params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
View view1 = inflater.inflate(R.layout.layout1, null);
addContentView(view1, default_layout_params);
View view2 = inflater.inflate(R.layout.layout2, null);
addContentView(view2, default_layout_params);
view2.setVisibility(View.INVISIBLE);
view1.setVisibility(View.VISIBLE);
view1.bringToFront();
layout2中还有另一个按钮返回到layout1,如下所示:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutParams default_layout_params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
View view1 = inflater.inflate(R.layout.layout1, null);
addContentView(view1, default_layout_params);
View view2 = inflater.inflate(R.layout.layout2, null);
addContentView(view2, default_layout_params);
view2.setVisibility(View.INVISIBLE);
view1.setVisibility(View.VISIBLE);
view1.bringToFront();
问题是,当我返回到布局1时,单击someBtn1的监听器就不工作了。似乎我需要为布局1的someBtn1再次设置OnClickListener。
我如何编写代码,使它们与最佳实践完美结合 如果您只想使用当前代码,那么问题的解决方案是在布局更改时必须重新声明侦听器,如下所示:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
}
});
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
}
});
}
});
避免两次声明侦听器的另一种方法是声明两种方法来处理布局更改,并在每个布局中使用按钮的onClick
属性,例如:
public void setLayout1(View view) {
setContentView(R.layout.layout1);
}
public void setLayout2(View view) {
setContentView(R.layout.layout2);
}
在layout1.xml
中:
<Button
android:id="@+id/someBtn1"
android:onClick="setLayout2"/>
<Button
android:id="@+id/someBtn2"
android:onClick="setLayout1"/>
但是,如果要遵循最佳实践,最佳实践不是在同一活动中混合布局,而是声明两个不同的活动(每个活动都有自己的布局),并根据单击的按钮调用一个或另一个活动。假设您在Activity1中,想要调用Activity2,然后返回Activity1:
在Activity1.java
中:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(this, Activity2.class));
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
在Activity2.java
中:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(this, Activity2.class));
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
在回调layout1时,必须再次设置数据
您可以将两个布局合并到一个布局中,然后使用ViewFlipper在它们之间进行切换。一种方法是将两个视图加载到onCreate(…)中,然后通过使不需要的视图不可见来在它们之间切换。如下所示:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutParams default_layout_params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
View view1 = inflater.inflate(R.layout.layout1, null);
addContentView(view1, default_layout_params);
View view2 = inflater.inflate(R.layout.layout2, null);
addContentView(view2, default_layout_params);
view2.setVisibility(View.INVISIBLE);
view1.setVisibility(View.VISIBLE);
view1.bringToFront();
在设置layout2时,还应该将OnClickListener设置为someBtn1,反之亦然,我建议这样做。但正如前面的回答一样,一般来说,您应该避免以这种方式混合布局
public class MainActivity extends Activity {
private final View.OnClickListener setLayout1Listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
((Button)findViewById(R.id.Btn2Id)).setOnClickListener(setLayout2Listener);
//do other stuff
}
};
private final View.OnClickListener setLayout2Listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
((Button)findViewById(R.id.Btn1Id)).setOnClickListener(setLayout1Listener);
//do other stuff
}
};
@Override
public void onCreate(final Bundle savedInstance) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
((Button)findViewById(R.id.Btn1Id)).setOnClickListener(setLayout1Listener);
//do other stuff
}
}
最佳做法是使用片段,而不是更改内容视图。 在代码中,setContentView with layouts每次都会重新创建(膨胀)所有视图,因此someBtn2 click listener中的调用setContentView(R.layout.layout1)将创建一个没有关联侦听器的新按钮 如果不想使用片段,可以执行以下操作:
private View view1, view2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view1 = getLayoutInflater().inflate(R.layout.layout1, null);
view2 = getLayoutInflater().inflate(R.layout.layout2, null);
setContentView(view1);
听众将是:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(view2);
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(view1);
}
});
是的,我知道。但由于某些原因,我希望在同一活动中动态使用不同的布局。谢谢你的建议。我已经改进了我的答案,以避免两次声明侦听器,请看一看。我想学习片段方式,你有任何快速示例吗?请阅读本文,并在SDK示例和Android支持库中查找示例(都可通过Android SDK管理器下载)我如何使底部返回按钮返回到上一个布局,但不返回到上一个活动?如果button1和button2在两个视图中具有相同的id怎么办?事实上,我正在与这种情况作斗争。实际上,我的两个视图上都有多个按钮,如果它们在做相同的工作,我不想为每个视图编写不同的侦听器。有什么解决方案吗?您可以从膨胀视图(view1.findViewById(…)中获取按钮,然后为其分配一个侦听器,该侦听器只需检查引用(view==view1),谢谢您的代码。实际上,我需要在一个活动中切换3-4个布局。这就是为什么我仍然困惑我应该用什么。在这种情况下使用Fragment更好吗?我刚刚发布了成功用于两个布局的代码。我很确定这种方法会更有效,但是
better
和best
是主观的,所以我将把选择权留给你!