我正在开发一个仅使用1个主要活动和多个片段的应用程序,其中包括ViewPager
,自定义视频/图片库,全屏片段(没有工具栏或底部导航按钮)。我不确定这是否是个好习惯,但是由于这个原因,我面临的问题很少。
上面的图像是实际的应用程序层次结构。我面临的问题之后。
using: getSupportActionBar().setDisplayHomeAsUpEnabled(true);
更改为后退箭头,则导航汉堡包会一直显示,然后后退箭头会打开抽屉,但不会返回最后一个片段。Fragment
内用单个Activity
完成所有任务是否是一种好习惯。我也在使用单个工具栏整个应用程序。 Toolbar.xml
<android.support.v7.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/primary"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/toolbar_connections"
android:visibility="visible"
android:orientation="horizontal">
<ImageView
android:layout_width="35dp"
android:layout_height="match_parent"
android:id="@+id/appLogo"
android:layout_gravity="center_vertical" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:textSize="22sp"
android:id="@+id/activityTitle"
android:textColor="@color/primary_text"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/toolbar_chat"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:src="@drawable/baby"
android:id="@+id/User_Image_Toolbar"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/User_Name_Toolbar"
android:textSize="17sp"
android:textStyle="bold"
android:layout_marginBottom="5dp"
android:text="My Name"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Online"
android:textStyle="italic"
android:id="@+id/User_Online_Status_Toolbar"
android:layout_marginBottom="5dp"
android:layout_below="@+id/User_Name_Toolbar" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.Toolbar>
导航抽屉(单个活动的所有片段的父项)
public class Navigation_Drawer extends AppCompatActivity implements UserData {
Toolbar toolbar;
DrawerLayout drawerLayout;
NavigationView navigationView;
String navTitles[];
TypedArray navIcons;
RecyclerView.Adapter recyclerViewAdapter;
ActionBarDrawerToggle drawerToggle;
public static final String TAG = "###Navigation Drawer###";
boolean nextScreen;
//Header
ImageView headerImage,headerUserImage;
TextView userName,userViews;
Context context = this;
//Setting Tabs
ViewPager viewPager;
TabAdapter tabAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navigation_drawer);
//Initialise Views
drawerLayout = findViewById(R.id.Navigation_Drawer_Main);
navigationView = findViewById(R.id.nvView);
setupToolbar();
navigationView.setItemIconTintList(null);
setupDrawerContent(navigationView);
settingHeaderItems();
drawerToggle = setupDrawerToggle();
getSupportActionBar().setHomeButtonEnabled(true);
drawerLayout.addDrawerListener(drawerToggle);
viewPager = findViewById(R.id.Navigation_Drawer_ViewPager);
tabAdapter = new TabAdapter(getFragmentManager(), this, false);
viewPager.setAdapter(tabAdapter);
}
public void setupToolbar() {
toolbar = findViewById(R.id.Navigation_Drawer_toolbar);
setSupportActionBar(toolbar);
}
private ActionBarDrawerToggle setupDrawerToggle() {
// NOTE: Make sure you pass in a valid toolbar reference. ActionBarDrawToggle() does not require it
// and will not render the hamburger icon without it.
//return new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
return new ActionBarDrawerToggle(this, drawerLayout,toolbar, R.string.drawer_open, R.string.drawer_close);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
// inflater.inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle Item Selection
return super.onOptionsItemSelected(item);
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
selectDrawerItem(menuItem);
return true;
}
});
}
public void ChangeFragment_ViewPager(int position, boolean outside) {
if (outside) {
Log.d(TAG, "Change Fragment Calling From Outside");
tabAdapter = new TabAdapter(getFragmentManager(), this, false);
viewPager.setAdapter(tabAdapter);
}
viewPager.setCurrentItem(position);
}
@Override
public void onBackPressed() {
super.onBackPressed();
showSystemUI();
Log.d(TAG, "On Back Pressed");
}
public void showSystemUI() {
if (getWindow() != null) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getSupportActionBar().show();
} else {
return;
}
}
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
switch (menuItem.getItemId()) {
case R.id.HeaderImageView:
fragment = new EditProfile();
break;
case R.id.home_Fragment:
Log.d(TAG,"Home Fragment Pressed ");
getFragmentManager().popBackStack(null, android.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
ChangeFragment_ViewPager(0,false);
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
drawerLayout.closeDrawers();
return;
case R.id.ppl_Fragment:
Log.d(TAG,"PPL Fragment Pressed ");
ChangeFragment_ViewPager(1,false);
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
drawerLayout.closeDrawers();
return;
case R.id.message_Fragment:
Log.d(TAG,"Message Fragment Pressed ");
fragment = new Messages_Fragment();
break;
case R.id.addMedia_Fragment:
Log.d(TAG,"Add Media Fragment Pressed ");
fragment = new UserProfile_Photos();
break;
case R.id.invite_Fragment:
Log.d(TAG,"Invite Fragment Pressed ");
//fragmentClass = fragment_1.class;
onInviteClicked();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
drawerLayout.closeDrawers();
return;
case R.id.setting_Fragment:
Log.d(TAG,"Setting Fragment Pressed ");
fragment = new Setting_NavigationDrawer();
break;
case R.id.help_Fragment:
Log.d(TAG,"Help Fragment Pressed ");
//fragmentClass = fragment_1.class;
fragment=new FullScreen_WebView();
Bundle urlToSend=new Bundle();
urlToSend.putString("webViewURL","http://boysjoys.com/test/Android/Data/help.php");
//urlToSend.putString("webViewURL",chat_wrapper.getGoogleSearch().get(2));
fragment.setArguments(urlToSend);
FragmentTransaction transaction=((Activity)context).getFragmentManager().beginTransaction();
//fragmentTrasaction.replace(R.id.Chat_Screen_Main_Layout,gallery);
//transaction.replace(R.id.Chat_Screen_Main_Layout,fullScreen_webView);
transaction.replace(R.id.Navigation_Main_Layout,fragment);
transaction.addToBackStack(null);
transaction.commit();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
drawerLayout.closeDrawers();
return;
case R.id.signOut_Fragment:
new CheckLoginStatus(this, 0).execute();
new Send_Session_Logout(this).execute();
drawerLayout.closeDrawers();
return;
}
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.Navigation_Main_Layout, fragment);
fragmentTransaction.setCustomAnimations(R.animator.enter_anim,R.animator.exit_anim);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
drawerLayout.closeDrawers();
}
private void settingHeaderItems(){
View HeaderLayout = navigationView.inflateHeaderView(R.layout.navigation_header_image);
//Main Screen Tabs With VIew Pager
headerImage = HeaderLayout.findViewById(R.id.HeaderImageView);
headerImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.Navigation_Main_Layout, new EditProfile());
fragmentTransaction.setCustomAnimations(R.animator.enter_anim,R.animator.exit_anim);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
drawerLayout.closeDrawers();
}
});
headerUserImage = HeaderLayout.findViewById(R.id.HeaderProfilePicture);
userName = HeaderLayout.findViewById(R.id.myImageViewText);
userViews = HeaderLayout.findViewById(R.id.profileViews);
if (Session.getUserCover().equals("Invalid Image")){
headerImage.setBackgroundResource(R.drawable.cam_icon);
}else {
Log.d(TAG,"Path Of Cover Photo "+Session.getUserCover());
Bitmap coverPhoto= BitmapFactory.decodeFile(Session.getUserCover());
headerImage.setImageBitmap(coverPhoto);
// Glide.with(context).load(Session.getUserCover()).apply(new RequestOptions().skipMemoryCache(true).onlyRetrieveFromCache(false).diskCacheStrategy(DiskCacheStrategy.NONE)).into(holder.HeaderImage);
}
Bitmap bitmap = BitmapFactory.decodeFile(Session.getUserImage());
userName.setText(Session.getUserFname()+" "+Session.getUserLname());
headerUserImage.setImageBitmap(bitmap);
if (Session.getProfileCounter().equals("0")){
userViews.setText("No Profile VIsits");
}
else {
userViews.setText("Profile views: "+ Session.getProfileCounter());
}
}
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
}
我非常想解决这个问题,经过数月的谷歌搜索和stackoverflow,我仍然陷于同一问题。
问题1的示例:-当导航抽屉首先加载时,一切看起来都很好,视图分页器会根据片段更改标题。然后,如果我单击导航抽屉菜单,它也会打开另一个片段(对于Ex:最近的消息)。然后标题更改成功,但是当我按返回按钮或尝试按主页按钮(调用viewpager)时,标题将保持不变,即“最近的消息”。
像这样在每个片段中设置标题。
toolbar = (Toolbar) getActivity().findViewById(R.id.Navigation_Drawer_toolbar);
ImageView appLogo = toolbar.findViewById(R.id.appLogo);
TextView fragmentTitle = toolbar.findViewById(R.id.activityTitle);
appLogo.setImageResource(DrawableImage);
fragmentTitle.setText(Title);
答案 0 :(得分:3)
在Fragment中执行所有任务是否是一种好习惯 单一活动。
与导航抽屉,选项卡或底部导航一起使用时,最好使用片段。
除此之外,对于具有不同数据的可重用UI,片段是首选。
您正在使用Single Activity 在片段中执行 所有任务 ,因此,我想这是一个好习惯。
按返回按钮或 单击按钮或某些链接前进。
每当添加/替换新片段时,您都需要手动设置片段的标题 OR
按下(退栈更改),仅通过Fragment或使用docs中所述的 OnBackStackChangedListener 。
您只是在浏览导航项时进行设置,而不是在 点击按钮或某些链接
时进行设置如果我更改为后退箭头,导航汉堡包将继续显示 使用:getSupportActionBar()。setDisplayHomeAsUpEnabled(true);然后 向后箭头可打开抽屉,但不会返回最后一个片段。
您也需要手动处理。在 android.R.id.home 项目上单击,使用 onOptionItemSelected 。 就像从堆栈弹出片段一样。
标题持续存在的原因是从“活动”中设置标题。
例如,使用此setTitle(menuItem.getTitle());
而不是通过Fragment来设置它们,或者如果您将它们设置为通过Fragment从selectDrawerItem
方法中删除。
同样在selectDrawerItem
方法的末尾,您使用的是fragmentTransaction.add
而不是fragmentTransaction.replace
答案 1 :(得分:3)
如果应用程序必须使用所有视图中都应包含的导航抽屉,则应使用Fragment。这不是一个坏习惯。
在基本活动中创建方法
public void setFragmentTitle(String title){
if(!TextUtils.isEmpty(title))
mTitleText.setText(title);
}
从onCreateView
的各个片段中访问此方法
((LandingActivity) getActivity()).setFragmentTitle(getActivity().getString(R.string.fragment_title));
导航汉堡包始终显示是否通过以下方式变为后退箭头:getSupportActionBar()。setDisplayHomeAsUpEnabled(true);然后向后箭头会打开抽屉,但不会返回最后一个片段。
在点击onOptionItemSelected
时使用android.R.id.home
,弹出当前的Fragment
按下后退按钮或直接跳到某些片段时片段状态丢失
您必须提及需要保留的值并重新填充。
public class ActivityABC....{
private String mFName;
private TableSelectFragment mFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
if (savedInstanceState != null) {
mFragment=(TableSelectFragment)fm.getFragment(savedInstanceState,"TABLE_FRAGMENT");
mFName = savedInstanceState.getString("FNAMETAG");
}else{
mFragment = new TableSelectFragment();
fm.beginTransaction().add(R.id.content_frame,mFragment,"TABLE_FRAGMENT").commit();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState,"TABLE_FRAGMENT",mFragment);
}
}
在您的片段中
TableSelectFragment{
....
private String mFName;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putString("FNAMETAG", mFName);
super.onSaveInstanceState(outState);
}
}
编辑1:对于片段标题未在BackButton中更新的情况,请按
将Fragment
添加到backstack时,请执行以下操作。
在您的父级活动中
FragmentManager fragMan = getSupportFragmentManager();
FragmentTransaction fragTrans = fragMan.beginTransaction();
LandingFrag landingFrag = LandingFrag.newInstance();
fragTrans.replace(R.id.landing_view, landingFrag,"LandingFrag");
fragTrans.addToBackStack(null);
fragTrans.commit();
landingFrag.setUserVisibleHint(true);
现在在父活动中覆盖onBackPressed
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
.. POP Fragment Backstack here
Fragment fragment = getActiveFragment();
if(fragment instanceof LandingFrag)
{
LandingFrag landingFrag = (LandingFrag)fragment;
landingFrag.setUserVisibleHint(true);
}
}
public Fragment getActiveFragment() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
return null;
}
Fragment fragment=null;
int trackBackValue = 1;//INCREASE OR DECREASE ACCORDING TO YOUR BACK STACK
try {
fragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - trackBackValue);
} catch (Exception e) {
}
return fragment;
}
现在进入LandingFrag
public class LandingFrag...
{
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUserVisibleHint(false);
.....
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
................
((LandingActivity) getActivity()).setFragmentTitle("Current Fragment Title");
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
try {
((LandingActivity) getActivity()).setFragmentTitle("Current Fragment Title");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}