TabActivity和TabHost+Fragment和FragmentTabHost的区别

TabActivity和TabHost+Fragment和FragmentTabHost的区别,第1张

//定义FragmentTabHost对象

private MyFragmentTabHost mTabHost;

//定义数组来存放Fragment界面

private Class fragmentArray[] = {BaseFragmentclass,BaseFragmentclass,BaseFragmentclass,BaseFragmentclass,BaseFragmentclass};

//Tab选项卡的文字

private String mTextviewArray[] = {"a", "b", "c", "d", "e"};

//实例化TabHost对象,得到TabHost

mTabHost = (SunnyFragmentTabHost)findViewById(androidRidtabhost);

mTabHostsetup(this, getSupportFragmentManager(), Ridrealtabcontent);

首先,我认为值得一提的是

"你不能替换静态定义的布局文件中的一个片段。您仅可替换你动态地添加通过 FragmentTransaction 的片段"

请参阅

Android: 不能替换另一个的一个片段

如何显示一个选项卡内的一个新片段?

这里是解决方案。

在 home_activityxml,你应该离开空你 tabcontent。

<FrameLayout

android:id="@+id/tabcontent"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1" />

您的 Home_Activity

private FragmentTabHost mHost;

public void changeFragment() {

FragmentTransaction ft = getSupportFragmentManager()beginTransaction();

EntertainmentFragment enFragment = new EntertainmentFragment();

ftreplace(Ridtabcontent, enFragment);

ftcommit();

}

@Override

protected void onCreate(Bundle savedInstanceState) {

superonCreate(savedInstanceState);

setContentView(Rlayoutactivity_main);

mHost = (FragmentTabHost) findViewById(androidRidtabhost);

mHostsetup(this, getSupportFragmentManager(), Ridtabcontent);

mHostaddTab(mHostnewTabSpec("School")

setIndicator("School"), SchoolFragmentclass, null);

mHostaddTab(mHostnewTabSpec("Sport")

setIndicator("Sport"), SportsFragmentclass, null);

}

您的 onIemClick (Sports_Fragment),添加这

MainActivity mainAct = (MainActivity)getActivity();

mainActchangeFragment();

我充分的项目,基于您的代码,是在这里。

我还没有机会真的检查 TabHost 为什么不工作时我测试您的代码。但FragmentTabHost的作品对我很好。

编辑: 若要修复重叠问题,您可以设置 OnTabChangeListener:

mHostsetOnTabChangedListener(new TabHostOnTabChangeListener() {

@Override

public void onTabChanged(String tabId) {

// TODO Auto-generated method stub

if (tabIdequalsIgnoreCase("School")) {

Logv(TAG, "school");

FragmentTransaction ft = getSupportFragmentManager()

beginTransaction();

schoolFrag = new SchoolFragment();

ftreplace(Ridtabcontent, schoolFrag);

ftcommit();

}

if (tabIdequalsIgnoreCase("Sport")) {

Logv(TAG, "Sport");

FragmentTransaction ft = getSupportFragmentManager()

beginTransaction();

SportsFragment sportFrag = new SportsFragment();

ftreplace(Ridtabcontent, sportFrag);

ftcommit();

}

}

});

关于 backpress,您可以尝试

ftaddToBackStack(null);

由于前段时间项目中使用到了自动换行的线性布局,本来打算用表格布局在里面一个个的用Java代码添加ImageView的,但是添加的View控件是不确定的,因为得靠服务器的数据返回,就这样手动用Java代码画布局的方式就这样夭折了,因为在表哥布局中我无法确定一行显示多少个ImageView的数目,所以无法动态添加,最后自能自己去看看那种能够换行的线性布局了,线性布局比较不好的是不能自动换行,也就是当设置LinearLayout的orentation 设置为vertical 为竖直方向也就是只有一列,每行只能显示一个View或者View的子类,当设置LinearLayout的orentitation为Horizontal,LinearLayout的只能显示为一行,横向显示,当屏幕满了的时候,View控件并不会自动换行,所以我们要做的就是在LinearLayout满的时候自动换行。\x0d\需要了解的是怎么样绘制根据子控件的长宽绘制父控件的宽度与高度,所以需要传入的参数控件的高度,视图分为两种一种是View类型的,代表控件有TextView,Button,EditText 等等,还有一种是装视图的容器控件继承自ViewGroup的控件,如LinearLayout,RelativeLayout,TabHost等等控件,需要自动换行的线性布局的话,就需要根据子控件的高度与宽度,来动态加载父控件的高度与宽度,所以需要在构造函数中传入每一个子控件的固定的高度,或者是动态设置子控件的高度与宽度。\x0d\将自定义的LinearLayout 也继承自ViewGroup 并且重写抽象类ViewGrouop的几个方法:onMeasure(),onLayout(),dispathDraw() 三个方法的意思分别是:第一个onMeasure()是用来计算控件以及子控件所占用的区域,第二个onLayout()是控制子控件的换行,第三个可写可不写,主要是用来绘制控件的边框,\x0d\自定义LinearLayout的代码如下:\x0d\\x0d\[java] view plaincopyprint\x0d\package comhuanglongmylinearlayout; \x0d\ \x0d\import androidcontentContext; \x0d\import androidgraphicsCanvas; \x0d\import androidgraphicsColor; \x0d\import androidgraphicsPaint; \x0d\import androidgraphicsRect; \x0d\import androidutilAttributeSet; \x0d\import androidviewView; \x0d\import androidviewViewGroup; \x0d\ \x0d\/ \x0d\ @author huanglong 2013-5-28 自定义自动换行LinearLayout \x0d\ / \x0d\public class FixGridLayout extends ViewGroup { \x0d\ private int mCellWidth; \x0d\ private int mCellHeight; \x0d\ \x0d\ public FixGridLayout(Context context) { \x0d\ super(context); \x0d\ } \x0d\ \x0d\ public FixGridLayout(Context context, AttributeSet attrs) { \x0d\ super(context, attrs); \x0d\ } \x0d\ \x0d\ public FixGridLayout(Context context, AttributeSet attrs, int defStyle) { \x0d\ super(context, attrs, defStyle); \x0d\ } \x0d\ \x0d\ public void setmCellWidth(int w) { \x0d\ mCellWidth = w; \x0d\ requestLayout(); \x0d\ } \x0d\ \x0d\ public void setmCellHeight(int h) { \x0d\ mCellHeight = h; \x0d\ requestLayout(); \x0d\ } \x0d\ \x0d\ / \x0d\ 控制子控件的换行 \x0d\ / \x0d\ @Override \x0d\ protected void onLayout(boolean changed, int l, int t, int r, int b) { \x0d\ int cellWidth = mCellWidth; \x0d\ int cellHeight = mCellHeight; \x0d\ int columns = (r - l) / cellWidth; \x0d\ if (columns = (columns - 1)) { \x0d\ i = 0; \x0d\ x = 0; \x0d\ y += cellHeight; \x0d\ } else { \x0d\ i++; \x0d\ x += cellWidth; \x0d\ \x0d\ } \x0d\ } \x0d\ } \x0d\ \x0d\ / \x0d\ 计算控件及子控件所占区域 \x0d\ / \x0d\ @Override \x0d\ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { \x0d\ // 创建测量参数 \x0d\ int cellWidthSpec = MeasureSpecmakeMeasureSpec(mCellWidth, MeasureSpecAT_MOST); \x0d\ int cellHeightSpec = MeasureSpecmakeMeasureSpec(mCellHeight, MeasureSpecAT_MOST); \x0d\ // 记录ViewGroup中Child的总个数 \x0d\ int count = getChildCount(); \x0d\ // 设置子空间Child的宽高 \x0d\ for (int i = 0; i 回答于 2022-11-18

1调用系统照相机

Intent intent = new Intent(MediaStoreACTION_IMAGE_CAPTURE);

startActivityForResult(intent, 1);

2 onActivityResult中处理回调

if (resultCode == ActivityRESULT_OK) {

String sdStatus = EnvironmentgetExternalStorageState();

if (!sdStatusequals(EnvironmentMEDIA_MOUNTED)) { // 检测sd是否可用

Logi("TestFile",

"SD card is not avaiable/writeable right now");

return;

}

String name = new DateFormat()format("yyyyMMdd_hhmmss",CalendargetInstance(LocaleCHINA)) + "jpg";

ToastmakeText(this, name, ToastLENGTH_LONG)show();

Bundle bundle = datagetExtras();

Bitmap bitmap = (Bitmap) bundleget("data");// 获取相机返回的数据,并转换为Bitmap格式

FileOutputStream b = null;

File file = new File("/sdcard/myImage/");

filemkdirs();// 创建文件夹

String fileName = "/sdcard/myImage/"+name;

try {

b = new FileOutputStream(fileName);

bitmapcompress(BitmapCompressFormatJPEG, 100, b);// 把数据写入文件

} catch (FileNotFoundException e) {

eprintStackTrace();

} finally {

try {

bflush();

bclose();

} catch (IOException e) {

eprintStackTrace();

}

}

((ImageView) findViewById(RidimageView))setImageBitmap(bitmap);// 将显示在ImageView里

}

首先,我认为值得一提的是

"你不能替换静态定义的布局文件中的一个片段。您仅可替换你动态地添加通过 FragmentTransaction 的片段"

请参阅

Android: 不能替换另一个的一个片段

如何显示一个选项卡内的一个新片段?

这里是解决方案。

在 home_activityxml,你应该离开空你 tabcontent。

<FrameLayout

android:id="@+id/tabcontent"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1" />

您的 Home_Activity

private FragmentTabHost mHost;

public void changeFragment() {

FragmentTransaction ft = getSupportFragmentManager()beginTransaction();

EntertainmentFragment enFragment = new EntertainmentFragment();

ftreplace(Ridtabcontent, enFragment);

ftcommit();

}

@Override

protected void onCreate(Bundle savedInstanceState) {

superonCreate(savedInstanceState);

setContentView(Rlayoutactivity_main);

mHost = (FragmentTabHost) findViewById(androidRidtabhost);

mHostsetup(this, getSupportFragmentManager(), Ridtabcontent);

mHostaddTab(mHostnewTabSpec("School")

setIndicator("School"), SchoolFragmentclass, null);

mHostaddTab(mHostnewTabSpec("Sport")

setIndicator("Sport"), SportsFragmentclass, null);

}

在您的 onIemClick (Sports_Fragment),添加这

MainActivity mainAct = (MainActivity)getActivity();

mainActchangeFragment();

我充分的项目,基于您的代码,是在这里。

我还没有机会真的检查 TabHost 为什么不工作时我测试您的代码。但FragmentTabHost的作品对我很好。

编辑: 若要修复重叠问题,您可以设置 OnTabChangeListener:

mHostsetOnTabChangedListener(new TabHostOnTabChangeListener() {

@Override

public void onTabChanged(String tabId) {

// TODO Auto-generated method stub

if (tabIdequalsIgnoreCase("School")) {

Logv(TAG, "school");

FragmentTransaction ft = getSupportFragmentManager()

beginTransaction();

schoolFrag = new SchoolFragment();

ftreplace(Ridtabcontent, schoolFrag);

ftcommit();

}

if (tabIdequalsIgnoreCase("Sport")) {

Logv(TAG, "Sport");

FragmentTransaction ft = getSupportFragmentManager()

beginTransaction();

SportsFragment sportFrag = new SportsFragment();

ftreplace(Ridtabcontent, sportFrag);

ftcommit();

}

}

});

关于 backpress,您可以尝试

ftaddToBackStack(null);

其他activity设置intent:Intent intent=new Intent();

intentputExtra("键",值);//intent键值对传的值

intentsetClass(FromActivitythis,TabHostActivityclass);

FromActivitythisstartActivity(intent);

tabhostacticity取得值并传值:

Intent intent=getIntent();

String value=intentgetStringExtra("键");

intentputExtra("另一键", 另一值);

intentsetClass(tabhostActivitythis, destclass);

ts1setContent(intent);

mTabHostaddTab(ts1);

目标activity取值:。。。。。。。。(不需要说了)

能不能滑动看一下代码: 

 package comexamplefragmentpageadapter;

import javautilList;

import androidosBundle;

import androidsupportv4appFragment;

import androidsupportv4appFragmentActivity;

import androidsupportv4appFragmentManager;

import androidsupportv4appFragmentPagerAdapter;

import androidsupportv4appFragmentTabHost;

public class MainActivity extends FragmentActivity {

private FragmentTabHost mTabHost = null;;

private List list;

@Override

protected void onCreate(Bundle savedInstanceState) {

superonCreate(savedInstanceState);

setContentView(Rlayoutfragments_tabs);

mTabHost = (FragmentTabHost) findViewById(androidRidtabhost);

mTabHostsetup(this, getSupportFragmentManager(), Ridrealtabcontent);

mTabHostaddTab(mTabHostnewTabSpec("0")setIndicator("新闻"),

NewsFragmentclass, null);

mTabHostaddTab(mTabHostnewTabSpec("1")setIndicator("音乐"),

LifeFragmentclass, null);

mTabHostaddTab(mTabHostnewTabSpec("2")setIndicator("人生"),

NewsFragmentclass, null);

}

@Override

protected void onDestroy() {

// TODO Auto-generated method stub

superonDestroy();

mTabHost = null;

}

}

2、fragments_tabsxml

[html] view plain copy print

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:id="@android:id/tabhost"

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@android:id/tabs"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"/>

android:id="@+id/realtabcontent"

android:layout_width="match_parent"

android:layout_height="match_parent"

/>

3、NewsFragmentjava

[java] view plain copy print

package comexamplefragmentpageadapter;

import androidosBundle;

import androidsupportv4appFragment;

import androidviewLayoutInflater;

import androidviewView;

import androidviewViewGroup;

public class NewsFragment extends Fragment {

@Override

public void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

superonCreate(savedInstanceState);

androidutilLogd("mark", "onCreate()--------->news Fragment");

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// TODO Auto-generated method stub

View view = inflaterinflate(Rlayoutnews, null);

androidutilLogd("mark", "onCreateView()--------->news Fragment");

return view;

}

@Override

public void onPause() {

// TODO Auto-generated method stub

superonPause();

androidutilLogd("mark", "onPause()--------->news Fragment");

}

}

先来看看整个demo的结构:

TabAFm到TabEFm都是Fragment,并且每个Fragment对应一个布局文件。

TabAFmjava:

View Code

如上述代码所示,TabAFm是一个Fragment,对应的布局文件是tab_axml,并实现了他的所有的生命周期回调函数并打印,便于调试

tab_axml布局中有个EditText

其他的Fragment大同小异,这里就不贴出代码了

现在来看MainActivity:

View Code

MainActivity上述代码所示

MainActivity是包含Fragment的Activity(也就是这里的5个Fragment)

他继承了FragmentActivity(因为我这里用的是android-support-v4jar)

用一个List<Fragment>去维护5个Fragment,也就是5个tab

main布局中有一个id为tab_content的FrameLayout,用来存放要显示的Fragment。底部有一个RadioGroup,用于tab的切换,如下:

View Code

现在回到MainActivity中,下面这个FragmentTabAdapter类是关键,是我自己编写的用于绑定和处理fragments和RadioGroup之间的逻辑关系

FragmentTabAdapter tabAdapter = new FragmentTabAdapter(this, fragments, Ridtab_content, rgs);

现在看下FragmentTabAdapter:

View Code

这里解决Fragment切换重新加载布局的办法,用的是把几个Fragment全部Add,然后根据要显示的哪个Fragment设置show或者hide

效果输出:

10-10 11:55:41168: INFO/Systemout(18368): AAAAAAAAAA____onAttach// 第一次进入,显示TabA

10-10 11:55:41168: INFO/Systemout(18368): AAAAAAAAAA____onCreate

10-10 11:55:41168: INFO/Systemout(18368): AAAAAAAAAA____onCreateView

10-10 11:55:41175: INFO/Systemout(18368): AAAAAAAAAA____onActivityCreated

10-10 11:55:41179: INFO/Systemout(18368): AAAAAAAAAA____onStart

10-10 11:55:41179: INFO/Systemout(18368): AAAAAAAAAA____onResume

10-10 11:55:44980: INFO/Systemout(18368): AAAAAAAAAA____onPause// 从TabA切换到TabB(TabA调用onPause)

10-10 11:55:44980: INFO/Systemout(18368): Extra---- 1 checked!!!

10-10 11:55:44996: INFO/Systemout(18368): BBBBBBBBBBB____onAttach

10-10 11:55:44996: INFO/Systemout(18368): BBBBBBBBBBB____onCreate

10-10 11:55:44996: INFO/Systemout(18368): BBBBBBBBBBB____onCreateView

10-10 11:55:45004: INFO/Systemout(18368): BBBBBBBBBBB____onActivityCreated

10-10 11:55:45004: INFO/Systemout(18368): BBBBBBBBBBB____onStart

10-10 11:55:45004: INFO/Systemout(18368): BBBBBBBBBBB____onResume

10-10 11:55:52062: INFO/Systemout(18368): BBBBBBBBBBB____onPause// 从TabB切换到TabC(TabB调用onPause)

10-10 11:55:52062: INFO/Systemout(18368): Extra---- 2 checked!!!

10-10 11:55:52082: INFO/Systemout(18368): CCCCCCCCCC____onAttach

10-10 11:55:52082: INFO/Systemout(18368): CCCCCCCCCC____onCreate

10-10 11:55:52086: INFO/Systemout(18368): CCCCCCCCCC____onCreateView

10-10 11:55:52090: INFO/Systemout(18368): CCCCCCCCCC____onActivityCreated

10-10 11:55:52090: INFO/Systemout(18368): CCCCCCCCCC____onStart

10-10 11:55:52090: INFO/Systemout(18368): CCCCCCCCCC____onResume

10-10 11:56:06535: INFO/Systemout(18368): CCCCCCCCCC____onPause// 从TabC切换到TabB(TabC调用onPause)

10-10 11:56:06535: INFO/Systemout(18368): BBBBBBBBBBB____onResume// 从TabC切换到TabB(TabB调用onResume)

10-10 11:56:06535: INFO/Systemout(18368): Extra---- 1 checked!!!

好了,到此为止,我们已经用Fragment实现了类似TabHost的功能了,下面来看下各个Fragment之间的通信

现在的情况是TabAFm中有个EditText,TabBFm中有个Button,MainActivity中有个变量“hello”

要做的是,切换到TabA,输入“I'm TabA”,切换到B,点击Button后,Toast显示“hello I'm TabA”

MainActivity中没什么好说的,就一个hello变量:

public String hello = "hello ";

TabAFm在布局文件tab_axml中加个EditText,设置个id就可以了

TabBFm中:

View Code

// 获得绑定的FragmentActivity

MainActivity activity = ((MainActivity)getActivity());

通过getActivity()即可得到Fragment所在的FragmentActivity

以上就是关于TabActivity和TabHost+Fragment和FragmentTabHost的区别全部的内容,包括:TabActivity和TabHost+Fragment和FragmentTabHost的区别、怎么判断fragment是否被添加、android LinearLayout 里面的东西怎么换行等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/9462025.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存