it-swarm.com.ru

Управление навигацией панели инструментов и кнопкой возврата из фрагмента в Android

Все мои фрагменты управляются с помощью ActionBarActivity (mainActivity), внутри mainActivity реализована DrawerLayout, и все дочерние фрагменты проталкиваются с помощью щелчка по элементу списка listLayout. Проблема, с которой я сталкиваюсь, заключается в том, что после проталкивания фрагмента через hookLayout я хочу изменить значок на выдвижном ящике на значок возврата ToolBar, чтобы пользователь мог перейти к предыдущему фрагменту и обработать обратный вызов Android.R.id.home либо внутри того же фрагмента, либо внутри mainActivity. ,.

Код, который я использую:

MainActivity.Java

public class MainActivity extends ActionBarActivity {
    private DrawerLayout layoutDrawer;
    private ActionBarDrawerToggle drawerToggler;
    private Stack<Fragment> stack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        stack = new Stack<Fragment>();
        layoutDrawer = (DrawerLayout) findViewById(R.id.layout_drawer);
        drawerToggler = new ActionBarDrawerToggle(this, layoutDrawer, toolbar,
                R.string.app_name, R.string.app_name);
        layoutDrawer.setDrawerListener(drawerToggler);

        setUpDrawerList();
        pushFragment(new FirstFragment(), true);

        Session.setContext(getApplicationContext());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (drawerToggler.isDrawerIndicatorEnabled()
                && drawerToggler.onOptionsItemSelected(item))
            return true;
        switch (item.getItemId()) {
        case Android.R.id.home:
            Toast.makeText(this, "Back from activity", Toast.LENGTH_SHORT)
                    .show();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggler.syncState();
    }

    @Override
    public void onBackPressed() {
        popFragment();
    }

    private void setUpDrawerList() {
        ListView listView = (ListView) findViewById(R.id.list_drawer);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                Android.R.layout.simple_list_item_1,
                Arrays.asList(new String[] { "First Fragment",
                        "Second Fragment" }));
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                layoutDrawer.closeDrawers();
                drawerToggler.setDrawerIndicatorEnabled(false);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                pushFragment(getFragment(position), true);
            }
        });
    }

    private Fragment getFragment(int pos) {
        switch (pos) {
        case 0:
            return new FirstFragment();
        case 1:
            return new SecondFragment();
        }
        return null;
    }

    public void pushFragment(Fragment fragment, boolean add) {
        FragmentTransaction transation = getSupportFragmentManager()
                .beginTransaction();
        if (add)
            stack.Push(fragment);
        transation.replace(R.id.layout_content, fragment);
        transation.commit();
    }

    public void popFragment() {
        if (!stack.isEmpty()) {
            Fragment fragment = stack.elementAt(stack.size() - 2);
            stack.pop();
            pushFragment(fragment, false);
        } else
            super.onBackPressed();
        drawerToggler.setDrawerIndicatorEnabled(stack.size() == 1);
    }

    public void clearBackStack() {
        stack.clear();
    }
}

FirstFragment.Java

public class FirstFragment extends Fragment {

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_first, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();
        ActionBar actionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
        actionBar.setTitle("First Fragment");
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        menu.clear();
        inflater.inflate(R.menu.fragment_menu, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
        case Android.R.id.home:
            Toast.makeText(getActivity(), "Back from fragment", Toast.LENGTH_SHORT).show();
            getActivity().onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Из приведенного выше кода я не могу получить обратный вызов Android.R.id.home и настройка кнопки home не работает каждый раз actionBar.setDisplayHomeAsUpEnabled(true);actionBar.setHomeButtonEnabled(true);

Любая помощь будет по достоинству оценена.

Спасибо

28
Abhishek Dhiman

Вы должны управлять нажатием кнопки «Назад» в своей основной Деятельности, потому что ваша основная Активность является контейнером для вашего фрагмента. 

Во-первых, добавьте весь свой фрагмент в-action.addToBackStack (null) , и теперь вызов кнопки "Назад" будет происходить в основном режиме. Я надеюсь, что следующий код поможет вам ...

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case Android.R.id.home:
        onBackPressed();
        }
    return super.onOptionsItemSelected(item);
}

вы также можете использовать 

Fragment fragment =fragmentManager.findFragmentByTag(Constant.TAG); 
if(fragment!=null) {          
      FragmentTransaction transaction = fragmentManager.beginTransaction();
      transaction.remove(fragment).commit();
}

И чтобы изменить заголовок в соответствии с именем фрагмента из фрагмента, вы можете использовать следующий код:

activity.getSupportActionBar().setTitle("Keyword Report Detail");
30
Amandeep Rohila

Добавить панель инструментов в ваш XML

<Android.support.v7.widget.Toolbar
    Android:id="@+id/toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="?attr/actionBarSize"
    Android:background="?attr/colorPrimary"
    Android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Fragment title"/>

</Android.support.v7.widget.Toolbar>

Затем внутри вашего метода onCreateView во фрагменте:

Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_button);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
         getActivity().onBackPressed();
    }
});
28
Vladimir Petrovski

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

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(false);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);// show back button
                toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onBackPressed();
                    }
                });
            } else {
                //show hamburger
                drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(true);
                getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                drawerFragment.mDrawerToggle.syncState();
                toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        drawerFragment.mDrawerLayout.openDrawer(GravityCompat.START);
                    }
                });
            }
        }
    });
21
Geek

Вы можете использовать панель инструментов внутри фрагмента, и с ней легко работать. Сначала добавьте панель инструментов в макет фрагмента

<Android.support.v7.widget.Toolbar
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/toolbar"
    Android:layout_height="wrap_content"
    Android:layout_width="match_parent"
    Android:fitsSystemWindows="true"
    Android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    Android:background="?attr/colorPrimaryDark">
</Android.support.v7.widget.Toolbar>

Внутри метода onCreateView во фрагменте вы можете обрабатывать панель инструментов следующим образом.

 Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
 toolbar.setTitle("Title");
 toolbar.setNavigationIcon(R.drawable.ic_arrow_back);

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

Если вам нужно вызвать какое-либо событие при нажатии на значок навигации на панели инструментов, вы можете использовать это.

 toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           //handle any click event
    });

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

 toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
            drawer.openDrawer(Gravity.START);
        }
    });

Полный код здесь

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //inflate the layout to the fragement
    view = inflater.inflate(R.layout.layout_user,container,false);

    //initialize the toolbar
    Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
    toolbar.setTitle("Title");
    toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //open navigation drawer when click navigation back button
            DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
            drawer.openDrawer(Gravity.START);
        }
    });
    return view;
}
7
Ishan Fernando

Наверное, самое чистое решение:

abstract class NavigationChildFragment : Fragment() {

    abstract fun onCreateChildView(inflater: LayoutInflater,
                                   container: ViewGroup?,
                                   savedInstanceState: Bundle?): View?

    override fun onCreateView(inflater: LayoutInflater,
                              container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val activity = activity as? MainActivity
        activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
        setHasOptionsMenu(true)
        return onCreateChildView(inflater, container, savedInstanceState)
    }

    override fun onDestroyView() {
        val activity = activity as? MainActivity
        activity?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
        setHasOptionsMenu(false)
        super.onDestroyView()
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val activity = activity as? MainActivity
        return when (item.itemId) {
            Android.R.id.home -> {
                activity?.onBackPressed()
                true
            }
            else              -> super.onOptionsItemSelected(item)
        }
    }
}

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

4
Appyx

На ToolBar есть значок навигации с левой стороны

Toolbar  toolbar = (Toolbar) findViewById(R.id.tool_bar);
        toolbar.setTitle(getResources().getString(R.string.title_activity_select_event));
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

При использовании этого слева на экране появляется значок навигации, а на значке навигации щелкните его, чтобы вызвать родительское действие. 

и в манифесте мы можем уведомить систему о родительской активности.

  <activity
            Android:name=".CategoryCloudSelectActivity"
            Android:parentActivityName=".EventSelectionActivity"
            Android:screenOrientation="portrait" />
0
Deepak Gupta