it-swarm.com.ru

Управление фрагментами навигационного ящика

 App Hierarchy Я занимаюсь разработкой приложения, в котором я использую только 1 основное действие и несколько фрагментов, включая ViewPager, пользовательскую галерею видео/изображений, полноэкранный фрагмент (без панели инструментов или нижней навигационной кнопки). Я не уверен, что это хорошая практика или нет, но я сталкиваюсь с несколькими причинами этого.

Изображение выше - фактическая иерархия приложения. После вопроса, с которым я сталкиваюсь.

  1. Панель инструментов не меняет название фрагмента, когда нажимает кнопку «Назад» или движется вперед, нажимая кнопку или какую-либо ссылку. 
  2. Навигационный гамбургер продолжает показывать, если я перехожу на стрелку назад с помощью using: getSupportActionBar().setDisplayHomeAsUpEnabled(true);, тогда стрелка назад открывает ящики, но не возвращается к последнему фрагменту.
  3. Потеря состояния фрагмента при нажатии кнопки назад или переходе непосредственно к какому-либо фрагменту.
  4. Является ли хорошей практикой выполнение всех задач внутри Fragment с помощью Single 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);
    }           
}

Я устал много, чтобы решить эту проблему, и после нескольких месяцев поиска в Google и stackoverflow я все еще застрял в той же проблеме.

Пример выдачи пункта 1: - При первой загрузке навигационной панели все выглядит хорошо, вид пейджера меняет заголовок в соответствии с фрагментом. затем, если я нажму на Меню Навигационного Ящика, которое также откроет другой фрагмент (Например: Недавнее Сообщение). затем заголовок успешно изменяется, но когда я нажимаю кнопку «Назад» или пытаюсь нажать кнопку «Домой», которая вызывает 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);
12
Ritu

Является ли хорошей практикой выполнение всех задач внутри фрагмента с помощью Одиночная активность.

Хорошей практикой является использование фрагментов при использовании с выдвижными ящиками, вкладками или нижней навигацией.
Кроме этого, фрагменты в основном предпочтительны для многоразового пользовательского интерфейса с другими данными.

Вы выполняете все задачи внутри фрагмента с Одиночным действием, потому что вы используете навигацию рисования и вкладки, так что это хорошая практика, я бы сказал. 

Панель инструментов не меняет заголовок фрагмента при нажатии кнопки «Назад» или идти вперед, нажав кнопку или какую-то ссылку.

Вам нужно вручную устанавливать заголовок для фрагмента всякий раз, когда вы добавляете/заменяете новый фрагмент ИЛИ
при обратном нажатии (изменение backstack), только через Fragment или с использованием OnBackStackChangedListener, как упомянуто в docs .

Вы просто настраиваете их, когда нажимаете на элементы навигации, а не когда кнопка или какая-то ссылка

Навигационный гамбургер продолжает показывать, превращаюсь ли я в стрелку назад на using: getSupportActionBar (). setDisplayHomeAsUpEnabled (true); затем стрелка назад открывает ящики, но не возвращается к последнему фрагменту.

Это тоже нужно обрабатывать вручную. используя onOptionItemSelected при щелчке элемента Android.R.id.home . Как извлечение фрагментов из стека. 

Причиной сохранения вашего заголовка на оборотной стороне является установка заголовка из Activity . То есть с помощью этой функции setTitle(menuItem.getTitle()); вместо этого установите их через Fragment или если вы устанавливаете их с помощью Fragment remove from selectDrawerItem method.
Также в конце метода selectDrawerItem вы используете fragmentTransaction.add вместо этого используйте fragmentTransaction.replace

3
Man

Если приложение должно использовать Навигационный ящик, который должен присутствовать во всех видах, следует использовать фрагмент. И это не плохая практика.

  1. Панель инструментов не меняет название фрагмента, когда нажимает кнопку «Назад» или , Нажимая кнопку или какую-либо ссылку.

Создать метод в Base Activity

public void setFragmentTitle(String title){
        if(!TextUtils.isEmpty(title))
        mTitleText.setText(title);
    }

Доступ к этому методу из ваших отдельных фрагментов в onCreateView

((LandingActivity) getActivity()).setFragmentTitle(getActivity().getString(R.string.fragment_title));
  1. Гамбургер навигации продолжает показывать, если я перехожу на стрелку назад, используя: getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); затем стрелка назад открывает ящики, но не возвращается к последнему фрагменту.

    Используйте onOptionItemSelected при нажатии Android.R.id.home, откройте текущую Fragment

  2. Потеря состояния фрагмента при нажатии кнопки назад или переходе к какому-либо фрагменту

    Вы должны упомянуть ценности, которые необходимо сохранить, и заполнить их.


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 в родительском Activity

    @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();
            }
        }
    }

}
3
Sreehari