底部导航初始设置当前项目未显示片段,重新启动片段失败



我有一个主活动,它使用 TabSelectedListener 来显示 AHBottomNavigation 菜单的片段。 名为"FirstFragment"的片段包含一个FragmentPagerAdapter,允许用户在两个选项卡之间滑动,每个选项卡都有自己的片段,称为FirstTabInFirstFragmentFragment和SecondTabInFirstFragmentFragment(为简单起见已重命名)。

我的问题是:

a). 启动主活动时,选择"第一个"底部导航菜单项,但不启动"第一个片段"。 因此,它显示在空白屏幕下选择的正确项目。 只有当我再次点击菜单项时,它才会启动第一个片段。

一旦第一个片段正确启动并显示在屏幕上(通过a中完成的临时修复),如果我选择不同的菜单项(即导航到第二片段),然后再次选择第一片段的菜单项,其中的两个选项卡是空白的。 此外,两个选项卡的片段之间的滑动不起作用并被"卡住",因此您必须将其一直拉到一侧或一直拉到另一侧。

希望我已经清楚地解释了我的问题 - 如果我缺少什么,我可以提供更多细节。
请注意,我正在使用com.aurelhubert.ahbottomnavigation.AHBottomNavigation
以下是相关文件:

主要活动.java

public class MainActivity extends AppCompatActivity{
private AHBottomNavigationAdapter navigationAdapter;
private AHBottomNavigationViewPager viewPager;
private AHBottomNavigation bottomNavigation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Add menu items to bar
bottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_navigation);
this.createNavItems();
bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
@Override
public boolean onTabSelected(int position, boolean wasSelected) {
//show fragment
if (position==0)
{
FirstFragment firstFragment=new FirstFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id,firstFragment).commit();
}else  if (position==1)
{
SecondFragment secondFragment=new SecondFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id, secondFragment).commit();
}else  if (position==2)
{
ThirdFragment thirdFragment=new ThirdFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id,thirdFragment).commit();
}else{
FourthFragment fourthFragment=new FourthFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id,fourthFragment).commit();
}
return true;
}
});
}
private void createNavItems(){
navigationAdapter = new AHBottomNavigationAdapter(this, R.menu.navigation);
navigationAdapter.setupWithBottomNavigation(bottomNavigation);
// set current item
bottomNavigation.setCurrentItem(0);
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_id"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"/>
</android.support.design.widget.CoordinatorLayout>

第一片段.java:

public class FirstFragment extends Fragment {
private FragmentActivity mContext;
public FirstFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);    
// Set the content of the activity to use the activity_main.xml layout file
//setContentView(R.layout.activity_first);
// Find the view pager that will allow the user to swipe between fragments
ViewPager viewPager = (ViewPager) getView().findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
// using getFragmentManager() will work too
FirstFragmentPagerAdapter adapter = new FirstFragmentPagerAdapter(mContext.getSupportFragmentManager(), mContext);
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) getView().findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
}
/**
* Override to set context.  This context is used for getSupportFragmentManager in onCreateView
* @param activity
*/
@Override
public void onAttach(Activity activity) {
mContext=(FragmentActivity) activity;
super.onAttach(activity);
}
}

fragment_first.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabBackground="@color/firstTabBackground"
app:tabIndicatorColor="@color/firstTabIndicatorColor"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"/>
</LinearLayout>

</android.support.constraint.ConstraintLayout>

FirstFragmentPagerAdapter.java:

public class FirstFragmentPagerAdapter extends FragmentPagerAdapter {
private Context context;
public FirstFragmentPagerAdapter(FragmentManager fm, Context mContext){
super(fm);
context = mContext;
}

/**
* The ViewPager asks the adapter for the fragment at a given position,
* i.e. for the 1st fragment, the ViewPager asks for the fragment at
* position 1.
* @param position
* @return
*/
@Override
public Fragment getItem(int position){
if (position == 0){
return new FirstTabInFirstFragmentFragment();
}
else{
return new SecondTabInFirstFragmentFragment();
}
}
/**
* On launch, the ViewPager asks the adapter how many pages there will be.
* Here, our adapter returns how many pages there will be.
* @return
*/
@Override
public int getCount() {return 2;}
@Override
public CharSequence getPageTitle(int position) {
switch(position){
case 0:
return context.getResources().getString(R.string.first_tab_in_first_fragment_page_title);
case 1:
return context.getResources().getString(R.string.second_tab_in_first_fragment_page_title);
default:
return null;
}
}
}

我能够通过两步解决这个问题。 首先,在我的主Activiy方法createNavItems中,除了做一个bottomNavigation.setCurrentItem(0);,我还不得不用默认片段手动更新CoordinatorLayout(它的ID为content_id):

getSupportFragmentManager().beginTransaction().replace(R.id.content_id, new FirstFragment()).commit();

接下来,为了解决 TabLayout 问题,我必须更改此行:

FirstFragmentPagerAdapter adapter = new FirstFragmentPagerAdapter(mContext.getSupportFragmentManager(), mContext);

FirstFragmentPagerAdapter adapter = new FirstFragmentPagerAdapter(getChildFragmentManager(), mContext);

这样做的原因是,当使用 ViewPager 将片段嵌套在其他片段中时,getFragmentManager()用于管理片段中的片段,而mContext.getSupportFragmentManager()用于活动。

首先,为了在启动时最初加载 frstfragment,您必须将 frstfragments 视图定义为主活动视图的默认视图。

其次,在选择底部导航菜单时,您需要有一个框架布局来加载每个片段的视图......在这里,您只是简单地替换了mainactivity的父布局,我认为这是一个错误的概念。

因此,您需要创建一个子框架布局来加载每个底部导航菜单项的片段视图。

编辑:

我的布局包含底部导航,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_home"
android:keepScreenOn="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ll_toolbar_home_search">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="@drawable/btn_style_white"
android:layout_marginRight="10dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="Search 18000+ products"
android:id="@+id/tv_search_home"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</LinearLayout>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/ll_toolbar_home_search"
android:layout_above="@+id/navigation"
android:id="@+id/frame_layout_fragment"
android:background="@color/white">
</FrameLayout>
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>

该活动的 Java 类(仅包含底部导航操作的方法)如下:

private void BottomView1() {
navigation = (AHBottomNavigation) findViewById(R.id.navigation);
AHBottomNavigationItem item1 = new AHBottomNavigationItem("Home", R.drawable.ic_home, R.color.ash);
AHBottomNavigationItem item2 = new AHBottomNavigationItem("Category", R.drawable.ic_category, R.color.ash);
AHBottomNavigationItem item3 = new AHBottomNavigationItem("Search", R.drawable.ic_search, R.color.ash);
AHBottomNavigationItem item4 = new AHBottomNavigationItem("Offers", R.drawable.ic_offers, R.color.ash);
AHBottomNavigationItem item5 = new AHBottomNavigationItem("Cart", R.drawable.ic_cart, R.color.ash);
navigation.addItem(item1);
navigation.addItem(item2);
navigation.addItem(item3);
navigation.addItem(item4);
navigation.addItem(item5);
navigation.setCurrentItem(getResources().getColor(R.color.colorPrimaryDark));
navigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);
setCartNotification();
navigation.setAccentColor(getResources().getColor(R.color.colorPrimaryDark));
navigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
@Override
public boolean onTabSelected(int position, boolean wasSelected) {
Intent ii ;
Fragment selectedFragment = null;
if(position==0){
selectedFragment = HomeFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout_fragment, selectedFragment);
transaction.commit();
} else if(position==1){
ii = new Intent(HomeActivity.this, ShopByCategoryActivity.class);
startActivity(ii);
} else if(position==2){
ii = new Intent(HomeActivity.this, SearchActivity.class);
startActivity(ii);
} else if(position==3){
ii = new Intent(HomeActivity.this, OffersActivity.class);
startActivity(ii);
} else if(position==4){
ii = new Intent(HomeActivity.this, MyCartActivity.class);
startActivity(ii);
}
return true;
}
});
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout_fragment, HomeFragment.newInstance());
transaction.commit();
}

最新更新