Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在android中动态设置布局_Java_Android_Android Layout_Android Intent - Fatal编程技术网

Java 如何在android中动态设置布局

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

好吧,假设有一个名为main活动的活动,有两个名为layout1layout2的布局都有几个按钮。默认情况下,MainActivity布局为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();
现在我实际做的是单击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
是主观的,所以我将把选择权留给你!