如何在安卓中动态设置布局

好吧,假设有一个名为MainActivity的活动,并且有两个名为 layout1layout2 的布局,它们都有几个按钮。默认情况下,MainActivity 布局是 layout1,如下所示:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout1);

现在我实际上所做的是通过单击 layout1 中的按钮,第二个布局的设置如下所示:

    someBtn1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            setContentView(R.layout.layout2);
        }
    });

layout2 中还有另一个按钮可返回到 layout1,如下所示:

    someBtn2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            setContentView(R.layout.layout1);
        }
    });

问题是当我返回到 layout1 时,someBtn1 的 OnClickListener 不起作用。看来我需要再次为 layout1某个Btn1 设置 OnClickListener。我如何编写代码以使它们与最佳实践完美配合?


答案 1

最佳做法是使用片段而不是更改内容视图。

在你的代码中,setContentView with layouts 每次都会重新创建(膨胀)你的所有视图,因此 someBtn2 单击侦听器中的 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);
    }
});

答案 2

如果您只想使用当前代码,则问题的解决方案是在布局更改时必须重新声明侦听器,如下所示:

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"/>

在:layout2.xml

<Button
    android:id="@+id/someBtn2"
    android:onClick="setLayout1"/>

但是,如果要遵循最佳做法,最佳做法不是在同一活动中混合布局,而是声明两个不同的活动(每个活动都有自己的布局),并根据单击的按钮调用一个活动或另一个活动。假设您位于活动 1 中,并且想要调用活动 2,然后返回到活动 1:

在:Activity1.java

someBtn1.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         startActivity(new Intent(this, Activity2.class));
     }
 });

在:Activity2.java

someBtn2.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         finish();
     }
 });

推荐