Tidak dapat menangkap acara klik tombol beranda toolbar

106

Saya telah menerapkan pustaka appcompat terbaru dan menggunakan Toolbarbilah tindakan as. Tapi masalahnya adalah saya tidak bisa menangkap acara klik tombol home / hamburger icon. Saya sudah mencoba dan melihat semuanya tetapi sepertinya tidak menemukan masalah yang sama.

Ini Activitykelas saya :

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

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Set up the drawer.
    navDrawerFragment = 
        (NavigationDrawerFragment) getSupportFragmentManager()
        .findFragmentById(R.id.navigation_drawer);
    navDrawerFragment.setUp(
        R.id.navigation_drawer, 
        (DrawerLayout) findViewById(R.id.drawer_layout), 
        toolbar);
}

Dan ini kelas NavigationDrawerFragment saya:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null) {
        currentSelectedPosition = savedInstanceState.getInt(
            STATE_SELECTED_POSITION);
        fromSavedInstanceState = true;
    }

    // Select either the default item (0) or the last selected item.
    selectItem(currentSelectedPosition);
}

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // Indicate that this fragment would like 
    // to influence the set of actions in the action bar.
    setHasOptionsMenu(true);
}

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        drawerListView = (ListView) inflater.inflate(
            R.layout.fragment_navigation_drawer, container, false);
        drawerListView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, 
                View view, int position, long id) {
                selectItem(position);
            }
        });
        //mDrawerListView.setAdapter();
        //mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
        return drawerListView;
}

public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
    fragmentContainerView = getActivity().findViewById(fragmentId);
    this.drawerLayout = drawerLayout;

    // set a custom shadow that overlays the main 
    // content when the drawer opens
    drawerLayout.setDrawerShadow(
        R.drawable.drawer_shadow, GravityCompat.START);
    // set up the drawer's list view 
    // with items and click listener

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeButtonEnabled(true);

    // ActionBarDrawerToggle ties together the the proper interactions
    // between the navigation drawer and the action bar app icon.
    drawerToggle = new ActionBarDrawerToggle(
        getActivity(), 
        drawerLayout, 
        toolbar, 
        R.string.navigation_drawer_open, 
        R.string.navigation_drawer_close) {
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
        }

        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
        }
    };

    // If the user hasn't 'learned' about the drawer, 
    // open it to introduce them to the drawer,
    // per the navigation drawer design guidelines.
    if (!userLearnedDrawer && !fromSavedInstanceState) {
        drawerLayout.openDrawer(fragmentContainerView);
    }

    // Defer code dependent on restoration of previous instance state.
    drawerLayout.post(new Runnable() {
        @Override
        public void run() {
            drawerToggle.syncState();
        }
    });

    drawerLayout.setDrawerListener(drawerToggle);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Forward the new configuration the drawer toggle component.
    drawerToggle.onConfigurationChanged(newConfig);
}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Log.d("cek", "item selected");
    if (drawerToggle.onOptionsItemSelected(item)) {
        Log.d("cek", "home selected");
        return true;
    }

    return super.onOptionsItemSelected(item);
}

ketika saya mengklik item menu, log "item yang dipilih" dipanggil. Tetapi ketika saya mengklik tombol beranda, itu membuka panel samping navigasi tetapi log "rumah yang dipilih" tidak pernah dipanggil. Saya telah menetapkan onOptionsItemSelectedmetode di dalam saya Activityjuga, tetapi masih belum dipanggil.

Dark Leonhart
sumber

Jawaban:

224

Jika Anda ingin tahu kapan rumah diklik AppCompatActivitymaka Anda harus mencobanya seperti ini:

Pertama beri tahu Android Anda ingin menggunakan milik Anda Toolbarsebagai ActionBar:

setSupportActionBar(toolbar);

Kemudian atur Beranda untuk ditampilkan melalui setDisplayShowHomeEnabledseperti ini:

getSupportActionBar().setDisplayShowHomeEnabled(true);

Terakhir, dengarkan peristiwa klik android.R.id.homeseperti biasa:

@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
    if (menuItem.getItemId() == android.R.id.home) {
        Timber.d("Home pressed");
    }
    return super.onOptionsItemSelected(menuItem);
}

Jika Anda ingin mengetahui kapan tombol navigasi diklik Toolbardi kelas selain AppCompatActivityAnda dapat menggunakan metode ini untuk menyetel ikon navigasi dan mendengarkan peristiwa klik di atasnya. Ikon navigasi akan muncul di sisi kiri Anda di Toolbarmana tombol "home" dulu berada.

toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_nav_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d("cek", "home selected");
    }
});

Jika Anda ingin tahu kapan hamburger diklik dan laci terbuka, Anda sudah mendengarkan peristiwa ini melalui onDrawerOpeneddan onDrawerClosedAnda ingin melihat apakah callback tersebut sesuai dengan kebutuhan Anda.

MrEngineer13
sumber
1
Sudah mencoba bagian pertama sebelumnya, tetapi tidak berhasil. Mencoba bagian kedua, dan berhasil. Tetapi ikon tidak berubah jika saya mendaftarkan bilah alat dengan laci navigasi. Satu pertanyaan lagi, apakah ada pengganti setDrawerIndicatorEnabled untuk ini? Saya sudah mencoba dengan laci navigasi baru ini dan mendapatkan kesalahan. Terima kasih
Dark Leonhart
Solusi kedua berhasil. Tapi bagaimana kita bisa mendeteksi tombol home diklik dan tombol laci di solusi kedua. Ketika saya mengklik ikon laci, itu tidak membuka laci.
Dory
2
Jika Anda menyetelNavigationOnClickListener untuk bilah alat, maka Anda kehilangan perilaku laci "asli" :(
IlyaEremin
7
Jadi sekarang kita membutuhkan pendengar klik terpisah ketika sebelumnya dalam fragmen kita bisa memeriksa android.R.id.home di onOptionsItemSelected ()? Itu sangat menjengkelkan
Daniel Wilson
1
re: Toolbar, jika Anda menyetel NavigationOnClickListener baru (menggunakan setNavigationOnClickListener), Anda dapat memulihkan NavDrawer nanti saat diperlukan dengan memanggil lagi setDrawerListener dengan ActionBarDrawerToggle Anda.
straya
24
    mActionBarDrawerToggle = mNavigationDrawerFragment.getActionBarDrawerToggle();
    mActionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // event when click home button
        }
    });

dalam kasus saya kode ini bekerja dengan sempurna

vuhung3990
sumber
Anda benar-benar hebat, berhasil, saya tidak pernah berpikir bahwa saya dapat menangani tombol kembali toolbar melalui DrawerToggle ..
Sai
Agar ActionBarDrawerToggle.setToolbarNavigationClickListener berfungsi, pertama-tama harus memanggil ini: mActionBarDrawerToggle.setHomeAsUpIndicator (R.drawable.menu_icon); mActionBarDrawerToggle.setDrawerIndicatorEnabled (false); dan kelola acara klik itu sendiri. (buka / tutup laci saat diklik)
luky
10

Ini adalah bagaimana saya melakukannya untuk kembali ke fragmen yang benar, sebaliknya jika Anda memiliki beberapa fragmen pada level yang sama, ia akan kembali ke fragmen pertama jika Anda tidak menimpa perilaku tombol kembali toolbar.

toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            finish();
        }
    });
Marcos
sumber
Apakah kita memiliki Metode klik "Ganti" di Kotlin?
Akhila Madari
@AkhilaMadari coba sesuatu seperti ini di Kotlin: val toolbar = findViewById (R.id.toolbar) as Toolbar setSupportActionBar (toolbar) toolbar.setNavigationOnClickListener {/ * lakukan sesuatu yang Anda inginkan * / finish ()}
Marcos
3

Saya pikir solusi yang benar dengan support library 21 adalah sebagai berikut

// action_bar is def resource of appcompat; 
// if you have not provided your own toolbar I mean  
Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
if (toolbar != null) {
    // change home icon if you wish
    toolbar.setLogo(this.getResValues().homeIconDrawable());
    toolbar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //catch here title and home icon click                          
        }                       
    });                 
}
Čikić Nenad
sumber
di this.getResValues().homeIconDrawable(), Siapa this?
LuisComS
Ini adalah sebuah aktivitas. Getresvalues ​​adalah metode saya, jadi tidak relevan di sini. Setlogo menerima id sumber daya yang dapat digambar.
Čikić Nenad
4
ini akan menangani klik pengguna di mana saja di seluruh bilah alat, saya rasa ini bukan yang dia tanyakan
Mina Fawzy
1

Saya telah menangani tombol kembali dan Beranda di Laci Navigasi seperti

public class HomeActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
    private ActionBarDrawerToggle drawerToggle;
    private DrawerLayout drawerLayout;
    NavigationView navigationView;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_home);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        resetActionBar();

        navigationView = (NavigationView) findViewById(R.id.navigation_view);
        navigationView.setNavigationItemSelectedListener(this);

        //showing first fragment on Start
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).replace(R.id.content_fragment, new FirstFragment()).commit();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //listener for home
        if(id==android.R.id.home)
        {  
            if (getSupportFragmentManager().getBackStackEntryCount() > 0)
                onBackPressed();
            else
                drawerLayout.openDrawer(navigationView);
            return  true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
       if (drawerLayout.isDrawerOpen(GravityCompat.START)) 
            drawerLayout.closeDrawer(GravityCompat.START);
       else 
            super.onBackPressed();
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Begin the transaction

        Fragment fragment = null;
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (id == R.id.nav_companies_list) {
            fragment = new FirstFragment();
            // Handle the action
        } 


        // Begin the transaction
        if(fragment!=null){

            if(item.isChecked()){
                if(getSupportFragmentManager().getBackStackEntryCount()==0){
                    drawer.closeDrawers();
            }else{
                    removeAllFragments();
                    getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE).replace(R.id.WikiCompany, fragment).commit();
                    drawer.closeDrawer(GravityCompat.START);
                }

            }else{
                removeAllFragments();
                getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE).replace(R.id.WikiCompany, fragment).commit();
                drawer.closeDrawer(GravityCompat.START);
            }
        }

        return true;
    }

    public void removeAllFragments(){
        getSupportFragmentManager().popBackStackImmediate(null,
                FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

    public void replaceFragment(final Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.WikiCompany, fragment).addToBackStack("")
                .commit();
    }


    public void updateDrawerIcon() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    Log.i("", "BackStackCount: " + getSupportFragmentManager().getBackStackEntryCount());
                    if (getSupportFragmentManager().getBackStackEntryCount() > 0)
                        drawerToggle.setDrawerIndicatorEnabled(false);
                    else
                        drawerToggle.setDrawerIndicatorEnabled(true);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }, 50);
    }

    public void resetActionBar()
    {
        //display home
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
    }

    public void setActionBarTitle(String title) {
        getSupportActionBar().setTitle(title);
    }
}

dan Di setiap yang onViewCreatedsaya panggil

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ((HomeActivity)getActivity()).updateDrawerIcon();
    ((HomeActivity) getActivity()).setActionBarTitle("List");
}
Zar E Ahmer
sumber
0

Beginilah cara saya menerapkan desain pra-material dan tampaknya masih berfungsi sekarang, saya telah beralih ke yang baru Toolbar. Dalam kasus saya, saya ingin memasukkan pengguna jika mereka mencoba membuka navigasi samping saat keluar, (dan menangkap acara sehingga navigasi samping tidak akan terbuka). Dalam kasus Anda, Anda tidak bisa return true;.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (!isLoggedIn() && item.getItemId() == android.R.id.home) {
        login();
        return true;
    }
    return mDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}
darnmason
sumber
Ah, saya lupa, saya menemukan bahwa saya tidak dapat menangkap klik tombol beranda dalam sebuah fragmen, saya mengajukan pertanyaan di sini dan menyarankan solusi yang secara manual meneruskan acara ke semua fragmen Anda. stackoverflow.com/q/21938419/1007151
darnmason
0

Saya mengubah DrawerLayout sedikit untuk mendapatkan kejadian dan dapat mengkonsumsi dan acara, seperti jika Anda ingin menggunakan actionToggle sebagai kembali jika Anda dalam tampilan detail:

public class ListenableDrawerLayout extends DrawerLayout {

    private OnToggleButtonClickedListener mOnToggleButtonClickedListener;
    private boolean mManualCall;

    public ListenableDrawerLayout(Context context) {
        super(context);
    }

    public ListenableDrawerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ListenableDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * Sets the listener for the toggle button
     *
     * @param mOnToggleButtonClickedListener
     */
    public void setOnToggleButtonClickedListener(OnToggleButtonClickedListener mOnToggleButtonClickedListener) {
        this.mOnToggleButtonClickedListener = mOnToggleButtonClickedListener;
    }

    /**
     * Opens the navigation drawer manually from code<br>
     * <b>NOTE: </b>Use this function instead of the normal openDrawer method
     *
     * @param drawerView
     */
    public void openDrawerManual(View drawerView) {
        mManualCall = true;
        openDrawer(drawerView);
    }

    /**
     * Closes the navigation drawer manually from code<br>
     * <b>NOTE: </b>Use this function instead of the normal closeDrawer method
     *
     * @param drawerView
     */
    public void closeDrawerManual(View drawerView) {
        mManualCall = true;
        closeDrawer(drawerView);
    }


    @Override
    public void openDrawer(View drawerView) {

        // Check for listener and for not manual open
        if (!mManualCall && mOnToggleButtonClickedListener != null) {

            // Notify the listener and behave on its reaction
            if (mOnToggleButtonClickedListener.toggleOpenDrawer()) {
                return;
            }

        }
        // Manual call done
        mManualCall = false;

        // Let the drawer layout to its stuff
        super.openDrawer(drawerView);
    }

    @Override
    public void closeDrawer(View drawerView) {

        // Check for listener and for not manual close
        if (!mManualCall && mOnToggleButtonClickedListener != null) {

            // Notify the listener and behave on its reaction
            if (mOnToggleButtonClickedListener.toggleCloseDrawer()) {
                return;
            }

        }
        // Manual call done
        mManualCall = false;

        // Let the drawer layout to its stuff
        super.closeDrawer(drawerView);
    }

    /**
     * Interface for toggle button callbacks
     */
    public static interface OnToggleButtonClickedListener {

        /**
         * The ActionBarDrawerToggle has been pressed in order to open the drawer
         *
         * @return true if we want to consume the event, false if we want the normal behaviour
         */
        public boolean toggleOpenDrawer();

        /**
         * The ActionBarDrawerToggle has been pressed in order to close the drawer
         *
         * @return true if we want to consume the event, false if we want the normal behaviour
         */
        public boolean toggleCloseDrawer();
    }

}
Adrian
sumber
0

Pendekatan termudah yang dapat kami lakukan adalah mengubah ikon beranda menjadi ikon yang dikenal dan membandingkan drawable (karena ikon android.R.id.home dapat berbeda untuk versi api yang berbeda.

jadi setel toolbar sebagai setSupportActionBar (_toolbar);

_toolbar.NavigationIcon = your_known_drawable_here;

   for (int i = 0; i < _toolbar.ChildCount; i++)
            {
                View v = _toolbar.GetChildAt(i);
                if (v is ImageButton)
                {
                    ImageButton imageButton = v as ImageButton;

                    if (imageButton.Drawable.GetConstantState().Equals(_bookMarkIcon.GetConstantState()))
                    {
                       //here v is the widget that contains the home  icon you can add your click events here 
                    }
                }
            }
Sajidh Zahir
sumber
0

Dalam kasus saya, saya harus meletakkan ikon menggunakan:

toolbar.setNavigationIcon(R.drawable.ic_my_home);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);

Dan kemudian dengarkan peristiwa klik dengan onOptionsItemSelected default dan id android.R.id.home

Diego Laballos
sumber
1
Ini tidak akan berhasil. android.R.id.hometidak pernah menembak
Trancer
0

Untuk siapa pun yang mencari implementasi Xamarin (karena acara dilakukan secara berbeda di C #), saya cukup membuat NavClickHandlerkelas ini sebagai berikut:

public class NavClickHandler : Java.Lang.Object, View.IOnClickListener
{
    private Activity mActivity;
    public NavClickHandler(Activity activity)
    {
        this.mActivity = activity;
    }
    public void OnClick(View v)
    {
        DrawerLayout drawer = (DrawerLayout)mActivity.FindViewById(Resource.Id.drawer_layout);
        if (drawer.IsDrawerOpen(GravityCompat.Start))
        {
            drawer.CloseDrawer(GravityCompat.Start);
        }
        else
        {
            drawer.OpenDrawer(GravityCompat.Start);
        }
    }
}

Kemudian, tetapkan tombol menu hamburger khusus seperti ini:

        SupportActionBar.SetDisplayHomeAsUpEnabled(true);
        SupportActionBar.SetDefaultDisplayHomeAsUpEnabled(false);
        this.drawerToggle.DrawerIndicatorEnabled = false;
        this.drawerToggle.SetHomeAsUpIndicator(Resource.Drawable.MenuButton);

Dan terakhir, tetapkan toggler menu laci a ToolbarNavigationClickListener dari tipe kelas yang saya buat sebelumnya:

        this.drawerToggle.ToolbarNavigationClickListener = new NavClickHandler(this);

Dan kemudian Anda memiliki tombol menu kustom, dengan event klik yang ditangani.

Trevor Hart
sumber
0

Coba kode ini

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if(id == android.R.id.home){
        //You can get 
    }
    return super.onOptionsItemSelected(item);
}

Tambahkan kode di bawah ini ke metode onCreate () Anda

ActionBar ab = getSupportActionBar();
    ab.setDisplayHomeAsUpEnabled(true);
Faxriddin Abdullayev
sumber