【背景】
折腾:
期间,需要在创建好的tab页面内,不依赖于xml文件设置布局,动态创建多个Group分组。
【折腾过程】
1.弄了半天,感觉对于Android中的UI架构不熟悉,一头雾水。
所以去看官网中关于UI架构的解释:
UI Overview | Android Developers
后来用如下代码:
public class MainActivity extends FragmentActivity {
//public class MainActivity extends Activity {
//public class MainActivity extends TabActivity {
/**
* The serialization (saved instance state) Bundle key representing the
* current tab position.
*/
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
// @SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//TabHost tabHost2 = getTabHost();
TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
tabHost.setup();
TabSpec spec1=tabHost.newTabSpec("Tab1");
//spec1.setContent(R.id.tab1);
spec1.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
// TextView txtView = new TextView(MainActivity.this);
// txtView.setText("Tab Text in createTabContent");
// return txtView;\
LinearLayout tab1AllGroup = new LinearLayout(MainActivity.this);
tab1AllGroup.setLayoutParams(
new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tab1AllGroup.setOrientation(LinearLayout.VERTICAL);
// //LinearLayout panel = (LinearLayout) findViewById(R.id.eachTab);
LinearLayout tab1Group1 = new LinearLayout(MainActivity.this);
tab1Group1.setLayoutParams(
new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tab1Group1.setOrientation(LinearLayout.VERTICAL);
TextView tab1Group1Text1 = new TextView(MainActivity.this);
tab1Group1Text1.setText("This is newly created tab: Tab 1 Group 1 Text 1");
tab1Group1Text1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 60));
tab1Group1.addView(tab1Group1Text1);
TextView tab1Group1Text2 = new TextView(MainActivity.this);
tab1Group1Text2.setText("This is newly created tab: Tab 1 Group 1 Text 2");
tab1Group1Text2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tab1Group1.addView(tab1Group1Text2);
// login button
final Button btnLogin = new Button(MainActivity.this);
btnLogin.setText("Login");
btnLogin.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
btnLogin.setGravity(Gravity.CENTER);
btnLogin.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
Log.d("pocketmagic.net", "_createForm click but");
}
});
tab1Group1.addView(btnLogin);
LinearLayout tab1Group2 = new LinearLayout(MainActivity.this);
tab1Group2.setLayoutParams(
new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tab1Group2.setOrientation(LinearLayout.VERTICAL);
TextView tab1Group2Text1 = new TextView(MainActivity.this);
tab1Group2Text1.setText("This is newly created tab: Tab 1 Group 2 Text 1");
tab1Group2Text1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 60));
tab1Group2.addView(tab1Group2Text1);
tab1AllGroup.addView(tab1Group1);
tab1AllGroup.addView(tab1Group2);
return tab1AllGroup;
}
});
spec1.setIndicator("Tab Text for setIndicator");
TabSpec spec2=tabHost.newTabSpec("Tab2");
spec2.setIndicator("Tab 2");
spec2.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
// return(new AnalogClock(MainActivity.this));
LinearLayout panel = new LinearLayout(MainActivity.this);
panel.setLayoutParams(
new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
panel.setOrientation(LinearLayout.VERTICAL);
//LinearLayout panel = (LinearLayout) findViewById(R.id.eachTab);
TextView tab2Text1 = new TextView(MainActivity.this);
tab2Text1.setText("This is newly created tab: Tab 2 Text 1");
tab2Text1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
panel.addView(tab2Text1);
return panel;
}
});
spec2.setIndicator("Tab 2");
tabHost.addTab(spec1);
tabHost.addTab(spec2);
}对应xml文件:
res/layout/activity_main.xml
的内容是:
<?xml version="1.0" encoding="utf-8"?>
<!--
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="MergeRootFrame" />
-->
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tabHost"
xmlns:android="http://schemas.android.com/apk/res/android">
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@android:id/tabs"/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/tabcontent">
<!--
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/eachTab"
android:orientation="vertical"
android:paddingTop="60px">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tab1"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab1"
android:id="@+id/txt1"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tab2"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 2"
android:id="@+id/txt2"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tab3"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 3"
android:id="@+id/txt3"/>
</LinearLayout>
-->
</FrameLayout>
</TabHost>是可以动态添加多个group:
和:
但是很明显存在很多问题:
(1)显示出来的内容,不是在tab内,而是在整个页面内
(2)多个group中间也是没有分隔开的。
3.现在先整理和记录一些心得:
问题1:找不到getTabHost
如果你的activity的类,不是继承自TabActivity,那么直接用getTabHost,则会提示你找不到此函数。
比如:
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabHost tabHost2 = getTabHost();只有改为:
//public class MainActivity extends FragmentActivity {
public class MainActivity extends TabActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabHost tabHost2 = getTabHost();才可以找到getTabHost。
问题2:最好不要再用TabActivity
上面的错误的该法,虽然是可以正常编译通过,但是不是好的做法。
以为你TabActivity现在已经废弃,不推荐再使用了。
参考:
Android之TabHost – 好寂寞先生 – 51CTO技术博客
问题3:Your TabHost must have a FrameLayout whose id attribute is ‘android.R.id.tabcontent’
如果你之前的Tab对应的xml定义中,缺少了对应的FrameLayout的tabcontent部分,比如:
<?xml version="1.0" encoding="utf-8"?>
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tabHost"
xmlns:android="http://schemas.android.com/apk/res/android">
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@android:id/tabs"/>
<!--
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/tabcontent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/eachTab"
android:orientation="vertical"
android:paddingTop="60px">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tab1"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab1"
android:id="@+id/txt1"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tab2"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 2"
android:id="@+id/txt2"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tab3"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 3"
android:id="@+id/txt3"/>
</LinearLayout>
</FrameLayout>
-->
</TabHost>则运行时,会出现异常:
02-27 16:54:43.642: W/dalvikvm(15932): threadid=1: thread exiting with uncaught exception (group=0x41abce10)
02-27 16:54:43.662: E/AndroidRuntime(15932): FATAL EXCEPTION: main
02-27 16:54:43.662: E/AndroidRuntime(15932): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mm.harthandheld/com.mm.harthandheld.UI.MainActivity}: java.lang.RuntimeException: Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2295)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.ActivityThread.access$700(ActivityThread.java:150)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.os.Handler.dispatchMessage(Handler.java:99)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.os.Looper.loop(Looper.java:176)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.ActivityThread.main(ActivityThread.java:5279)
02-27 16:54:43.662: E/AndroidRuntime(15932): at java.lang.reflect.Method.invokeNative(Native Method)
02-27 16:54:43.662: E/AndroidRuntime(15932): at java.lang.reflect.Method.invoke(Method.java:511)
02-27 16:54:43.662: E/AndroidRuntime(15932): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
02-27 16:54:43.662: E/AndroidRuntime(15932): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
02-27 16:54:43.662: E/AndroidRuntime(15932): at dalvik.system.NativeStart.main(Native Method)
02-27 16:54:43.662: E/AndroidRuntime(15932): Caused by: java.lang.RuntimeException: Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.widget.TabHost.setup(TabHost.java:170)
02-27 16:54:43.662: E/AndroidRuntime(15932): at com.mm.harthandheld.UI.MainActivity.onCreate(MainActivity.java:97)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.Activity.performCreate(Activity.java:5267)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
02-27 16:54:43.662: E/AndroidRuntime(15932): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
02-27 16:54:43.662: E/AndroidRuntime(15932): ... 11 more而把对应的FrameLayout的tabcontent加上,即可:
<?xml version="1.0" encoding="utf-8"?>
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tabHost"
xmlns:android="http://schemas.android.com/apk/res/android">
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@android:id/tabs"/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@android:id/tabcontent">
<!--
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/eachTab"
android:orientation="vertical"
android:paddingTop="60px">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tab1"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab1"
android:id="@+id/txt1"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tab2"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 2"
android:id="@+id/txt2"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tab3"
android:orientation="vertical"
android:paddingTop="60px">
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 3"
android:id="@+id/txt3"/>
</LinearLayout>
-->
</FrameLayout>
</TabHost>可参考:
Android TabHost,TabWidget选项卡总结-Android开发问题解答-eoe Android开发者社区_Android开发论坛 – Powered by Discuz!
TabWidget/TabHost的两种使用方法 – 榴莲酥博客 – eoe移动开发者社区
问题4:TabHost,TabWidget,Tab content,FrameLayout之间的关系
可以参考:
TabView (Part 1) – Simple tab control in Android | Android Tech(需要翻墙)
和:
对TabHost、TabWidget的理解分析 – Alex_Michel – 51CTO技术博客
【继续折腾】
1.另外想起来了,此处应该是去找Android中的类似于Windows中的GroupBox的东西的。
所以再去搜:
android groupbox
2.找到:
Android: how to make a GroupBox widget? – Stack Overflow
找到这个讨论:
Border around a LinearLayout / rounded edges – Google Groups
但是没用。
原先帖子中,有人自己用代码模拟了一个,但是狂复杂。。。
3.参考:
android 布局,有没有类似mfc 中groupbox的控件-CSDN论坛-CSDN.NET-中国最大的IT技术社区
去找找
android CheckBoxPreference
找到:
官网的:
CheckBoxPreference | Android Developers
其他的示例:
Android的设置界面及Preference使用 – ichliebephone的专栏 – 博客频道 – CSDN.NET
很明显,不是所希望的groupbox的效果。。。
4.真是忍不住吐槽,Android中竟然不内置支持GroupBox这种控件。。。
5.参考:
Border around a LinearLayout / rounded edges – Google Groups
提到的:
how to put a border around an android textview – Stack Overflow
有空再去试试效果,最后弄出个基本的效果:
(1)添加xml去配置背景
在项目的/res/drawable下面加上一个group_background.xml
内容为:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#ff0000" /> <stroke android:width="3dip" android:color="#4fa5d5"/> </shape>
(2)在原先的代码中,添加对应的setBackgroundResource
此处,是参考:
how to put a border around an android textview – Stack Overflow
而去找了官方的:
中的:
android:background setBackgroundResource(int) A drawable to use as the background. |
而发现,我对于View类的东西(此处的我的是LinearLayout)除了可以静态的在xml中配置对应的android:background的属性之外,也可以动态的通过代码setBackgroundResource去设置的。
代码为:
LinearLayout tab1Group1 = new LinearLayout(tabContext);
tab1Group1.setLayoutParams(
new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tab1Group1.setOrientation(LinearLayout.VERTICAL);
tab1Group1.setBackgroundResource(R.drawable.group_background);
然后运行效果如下:
其中可见:
此处背景色故意设置为了红色,边框是淡蓝色。
算是基本模拟出来外部有边框的groupbox的效果了。。。
6.再去新建多个groupbox试试,但是用如下代码:
final TabHost tabHost = (TabHost)findViewById(R.id.tabHost);
tabHost.setup();
//final Context tabContext = tabHost.getContext();
final Context tabContext = MainActivity.this;
TabSpec spec1=tabHost.newTabSpec("Tab1");
//spec1.setContent(R.id.tab1);
spec1.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
// TextView txtView = new TextView(tabContext);
// txtView.setText("Tab Text in createTabContent");
// return txtView;\
// LinearLayout tab1AllGroup = new LinearLayout(tabContext);
// tab1AllGroup.setLayoutParams(
// new LayoutParams(
// LayoutParams.FILL_PARENT,
// LayoutParams.WRAP_CONTENT));
// tab1AllGroup.setOrientation(LinearLayout.VERTICAL);
FrameLayout tab1AllGroup = (FrameLayout) findViewById(android.R.id.tabcontent);
//LinearLayout panel = (LinearLayout) findViewById(R.id.eachTab);
LinearLayout tab1Group1 = new LinearLayout(tabContext);
tab1Group1.setLayoutParams(
new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tab1Group1.setOrientation(LinearLayout.VERTICAL);
tab1Group1.setBackgroundResource(R.drawable.group_background);
TextView tab1Group1Text1 = new TextView(tabContext);
tab1Group1Text1.setText("This is newly created tab: Tab 1 Group 1 Text 1");
//tab1Group1Text1.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 60));
tab1Group1.addView(tab1Group1Text1);
TextView tab1Group1Text2 = new TextView(tabContext);
tab1Group1Text2.setText("This is newly created tab: Tab 1 Group 1 Text 2");
//tab1Group1Text2.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
tab1Group1.addView(tab1Group1Text2);
LinearLayout tab1Group2 = new LinearLayout(tabContext);
tab1Group2.setLayoutParams(
new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tab1Group2.setOrientation(LinearLayout.VERTICAL);
tab1Group2.setBackgroundResource(R.drawable.group_background);
// login button
final Button btnLogin = new Button(tabContext);
btnLogin.setText("Login");
btnLogin.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
btnLogin.setGravity(Gravity.CENTER);
btnLogin.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
Log.d("pocketmagic.net", "_createForm click but");
}
});
tab1Group2.addView(btnLogin);
LinearLayout tab1Group3 = new LinearLayout(tabContext);
tab1Group3.setLayoutParams(
new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tab1Group3.setOrientation(LinearLayout.VERTICAL);
TextView tab1Group2Text1 = new TextView(tabContext);
tab1Group2Text1.setText("This is newly created tab: Tab 1 Group 2 Text 1");
tab1Group2Text1.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 60));
tab1Group3.addView(tab1Group2Text1);
tab1AllGroup.addView(tab1Group1);
tab1AllGroup.addView(tab1Group2);
tab1AllGroup.addView(tab1Group3);
return tab1AllGroup;
}
});
spec1.setIndicator("Tab 1");
TabSpec spec2=tabHost.newTabSpec("Tab2");
spec2.setIndicator("Tab 2");
spec2.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
// return(new AnalogClock(tabContext));
LinearLayout panel = new LinearLayout(tabContext);
panel.setLayoutParams(
new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
panel.setOrientation(LinearLayout.VERTICAL);
//LinearLayout panel = (LinearLayout) findViewById(R.id.eachTab);
TextView tab2Text1 = new TextView(tabContext);
tab2Text1.setText("This is newly created tab: Tab 2 Text 1");
tab2Text1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
panel.addView(tab2Text1);
return panel;
}
});
spec2.setIndicator("Tab 2");
tabHost.addTab(spec1);
tabHost.addTab(spec2);
}结果是:
tab内的多个group,全部都重叠了。搞得只能看到最后一层的内容。
【总结】
算了,很明显,实际上此处新建多个group已经解决了。
但是显示很错乱,那是由于之前就存在的问题:
【未解决】Android中的TabHost中的TAB中的FrameLayout中的View出现重叠且覆盖了TAB标签
转载请注明:在路上 » 【已解决】android中在Tab页面中动态创建多个Group