I just ran into some problem with my project main activity.
I have a SherlockFragmentActivity with a NavigationDrawer and a SearchView on the ActionBar with a custom view.
The problem is when I type a query on my SearchView, I can do my search and all works fine, but when I close the SearchView, my ActionBar custom view and NavigationDrawer toggle disappear from the ActionBar.
Here is the graphical problem
Here is my NavigationDrawer
private void initialiseDrawer(){
this.drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
this.drawerList = (ListView)findViewById(R.id.navigation_drawer);
this.drawerAdapter = new NavigationDrawerAdapter(MainActivity.this);
this.drawerList.setAdapter(drawerAdapter);
this.drawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
handleDrawerSelectedPosition(position);
}
});
//getSupportActionBar().setHomeButtonEnabled(true);
this.drawerToggle = new ActionBarDrawerToggle(this, this.drawerLayout, R.drawable.drawer,
R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View view){
super.onDrawerOpened(view);
hideMenu();
}
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
showMenu();
}
};
this.drawerLayout.setDrawerListener(drawerToggle);
this.drawerToggle.syncState();
}
And this is how I set my ActionBar
private void showCustomActionBarView(){
getSupportActionBar().setDisplayShowHomeEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setCustomView(R.layout.action_bar_layout);
}
What can I do to show my custom View and DrawerToggle after the SearchView has been dettached?
Well, I found my own answer here, I was using SherlockActionBar and the support libraries 4.0, I just removed the sherlock libraries and upated my support libraries to v7.21.03, implemented Toolbar and every issue went out, hope it helps somebody else than me
Related
This guide explains how to use NavigationComponent to make it easier to use the menu in the toolbar. All great when it comes to Activity but, how can I do the same thing with a fragment?
My project has 3 fragments: Login,Map,Settings.
The Login fragment has no toolbar, so the rest all have a custom toolbar.
The Map fragment has in the toolbar the menu that server to reach the Settings fragment.
This is how I added the toolbar in my Map fragment:
private void setupToolbar(View view) {
mNavController = Navigation.findNavController(view);
AppBarConfiguration appBarConfiguration =
new AppBarConfiguration.Builder(R.id.settingsFragment, R.id.mapsFragment).build();
NavigationUI.setupWithNavController(
mToolbar, mNavController, appBarConfiguration);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
return NavigationUI.onNavDestinationSelected(item, mNavController)
|| super.onOptionsItemSelected(item);
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
}
Obviously i call setHasOptions(true) inside the OnCreateView of the Map fragment.
The setUpToolbar method is called inside the OnViewCreate of the Map fragment.
This code allows me to show the toolbar inside the Map fragment but what it doesn't allow me to do is to reach (Using the navigation component) the settings fragment by clicking on the menu.
And, yes, the menu id is the same as the fragment name.
Solved
The call to the setSupportActionBar method in the onCreateView of the Map fragment was missing
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentMapsBinding.inflate(inflater, container, false);
((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
setHasOptionsMenu(true);
return binding.getRoot();
}
In my app I have problem like this. Note that I'm working with fragments and I have drawer too.
That's the method in my MainActivity for drawer open/close.
public void drawerInit() {
toolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer);
view = findViewById(R.id.mainView);
toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
float moveFactor = (drawerView.getWidth() * slideOffset);
view.setTranslationX(moveFactor);
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
drawer.addDrawerListener(toggle);
toggle.syncState();
}
Example I have 3 fragments (F1, F2, F3). F1 is my main fragment where I can open and close the drawer. When I'm opening F2 or F3 fragments, I need to change the drawer icon to back arrow. I'm doing this part successfully, but the problem is when I'm clicking on this back arrow, that opens the navigation drawer instead of going back. So how can I fix this part?
Here the part, where I'm changing the icon to back arrow in fragment.
((AppCompatActivity) getActivity()).getSupportActionBar().show();
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((AppCompatActivity) getActivity()).getSupportActionBar().setHomeButtonEnabled(true);
Add in your Activity
public void crateMenuButton(){
toggle.setDrawerIndicatorEnabled(true);
if(toolbarDrawable == null) {
toolbarDrawable = toolbar.getNavigationIcon();
}
toolbar.setNavigationIcon(toolbarDrawable);
invalidateOptionsMenu();
toggle.syncState();
}
public void createBackButton() {
toggle.setDrawerIndicatorEnabled(false);
toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//if the drawerToggle is disabled, fall off to the home button action
if (!toggle.isDrawerIndicatorEnabled()) {
// pop fragment here
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
}
} else {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawer(navigationView);
} else {
drawerLayout.openDrawer(navigationView);
}
}
}
});
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white));
}
Download Back Arrow
Then call from your fragment as your need
((YourActivity) getActivity()).createBackButton();
OR
((YourActivity) getActivity()).crateMenuButton();
I managed to create a drawer and have the hamburger sign but the hamburger is not working when tapped. Also how can I change the code so that my app has a transparent notification bar so that the color is same(or preferably a little darker) and one can see the app drawer opened in status bar. Something like this: Transparent status bar
FirstActivity.java:
public class FirstActivity extends AppCompatActivity {
DrawerLayout mDrawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_me_clicked);
Toolbar toolbar= (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false); //removes the package name from toolbar
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Window w = getWindow(); // in Activity's onCreate() for instance //Integration of app into status bar
// w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
// }
// These lines are needed to display the top-left hamburger button
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Make the hamburger button work
mDrawer = (DrawerLayout) findViewById(R.id.DL);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this,mDrawer,R.string.app_name,R.string.app_name){
#Override
public void onDrawerClosed(View drawerView) {
}
#Override
public void onDrawerOpened(View drawerView) {
}
};
mDrawer.addDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
// toasts the message when ListView item is clicked
ListView mDrawerListView = (ListView) findViewById(R.id.left_drawer);
mDrawerListView.setOnItemClickListener(new ListView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String drawerstring = ("Menu Item at position " + position + " clicked.");
mDrawer.closeDrawer(GravityCompat.START);
Toast.makeText(getApplicationContext(),drawerstring,Toast.LENGTH_SHORT).show();
}
});
}
You have to override onOptionsItemSelected and handle the home item to open the drawer. Its not done for you, because Android doesn't know what you're using that button for (home? back? hamburger? Something else?). The ActionDrawerToggle knows how to handle it if you want to just delegate it.
I'm still working with dragging listview (example from google https://www.youtube.com/watch?v=_BZIvjMgH-Q) - long click by listview item - goes dragging and I want to implement context menu on short click, but my changes do not seem towork. After short click on listview item goes dragging effect..
here is my code for activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utils.changeTheme(this,getApplicationContext());
Utils.setLang(this,getApplicationContext());
setContentView(R.layout.activity_list);
listView = (DynamicListView) findViewById(R.id.listview);
adapter = new StableArrayAdapter(this, R.layout.text_view, productsArray);
listView.setList(productsArray);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
registerForContextMenu(listView);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
view.showContextMenu();
}
});
}
With simple listview, short click working without any problems...
Could anybody explain what I'm doing wrong?
Thx in advance!
The best solution in this case is use popup menu instead of context menu.
I am trying to implement a navigation drawer in a BaseActivity, that shows different options depending on the activity that is currently showing. For that, I developed a BaseActivity, that implements the navigation drawer, and decides what to show, depending on the activity that is currently showing. The purpose of this, is to make all other activities that need to use the navigation drawer, expand the BaseActivity.
The following code, shows no errors, but the navigation drawer shows itself completely empty, and does not show when I click the 'home' button, neither the 'menu' button, a functionality that I implemented with the 'onKeyDown' method. It just shows, when I use the following gesture: move the finger from the left to the right in the left side of the screen.
When I do the same in each class I need, instead of using a BaseActivity, everything works perfeclty fine.
I have been trying this for days now and I still do not understand why, the content of the navigation drawer is still not showing. I would appreciate some help please. Thanks in advance.
Here, the core classes of the problem:
BaseActivity.java
public abstract class BaseActivity extends ActionBarActivity
{
public DrawerLayout drawerLayout = null;
public ActionBarDrawerToggle drawerToggle = null;
public Activity currentActivity = null;
public ArrayList<Item> navDrawerItems = new ArrayList<Item>();
public ItemListAdapter adapter = null;
public ListView drawerList = null;
int id = 0;
protected void onCreate(Bundle savedInstanceState, int resLayoutID)
{
super.onCreate(savedInstanceState);
setContentView(resLayoutID);
currentActivity = this;
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(currentActivity,
drawerLayout,
R.drawable.ic_drawer,
R.string.open_menu,
R.string.close_menu)
{
public void onDrawerClosed(View view)
{
Log.e("", "Close drawer");
getSupportActionBar().setTitle(getTitle());
ActivityCompat.invalidateOptionsMenu(currentActivity);
}
public void onDrawerOpened(View drawerView)
{
Log.e("", "Open drawer");
getSupportActionBar().setTitle(getTitle());
ActivityCompat.invalidateOptionsMenu(currentActivity);
}
};
drawerLayout.setDrawerListener(drawerToggle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
// Populate navigation drawer depending on the activity
// that is currently showing.
if (this.getClass().getSimpleName().equals("Z"))
setUpNavigationForZActivity();
}
private void setUpNavigationForZActivity()
{
Log.e("", "In setUpNavigationForZActivity");
// Prepare list items.
id = R.string.title_activity_A;
navDrawerItems.add(new NavigationDrawerItem(getString(id), Utils.activityIcon().get(id)));
id = R.string.title_activity_B;
navDrawerItems.add(new NavigationDrawerItem(getString(id), Utils.activityIcon().get(id)));
// Populate view.
drawerList = (ListView) findViewById(R.id.left_menu);
adapter = new ItemListAdapter(currentActivity, navDrawerItems;
drawerList.setAdapter(adapter);
drawerList.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position,
long id)
{
Intent intent = null;
switch(position)
{
case 0:
intent = new Intent(currentActivity, A.class);
startActivity(intent)
break;
case 1:
intent = new Intent(currentActivity, B.class);
startActivity(intent)
break;
default:
}
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (drawerToggle.onOptionsItemSelected(item))
return true;
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent e)
{
Log.e("", "onKeyDown");
if (keyCode == KeyEvent.KEYCODE_MENU)
{
if(!drawerLayout.isDrawerOpen(Gravity.LEFT))
drawerLayout.openDrawer(Gravity.LEFT);
else
drawerLayout.closeDrawer(Gravity.LEFT);
}
return super.onKeyDown(keyCode, e);
}
}
Z.java
public class Z extends BaseActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState, R.layout.Z);
setContentView(R.layout.Z);
//Other things to do...
}
}
Z.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Main content view -->
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true" >
// Other layout and views configurations...
</ScrollView>
<!-- Navigation drawer -->
<ListView
android:id="#+id/left_menu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/gray_7_5"
android:choiceMode="singleChoice" />
</android.support.v4.widget.DrawerLayout>
I do not exactly know why you would want to implement it that way but if you still want to do it this way i would suggest making your navdrawer use a listview with an adapter to draw items from an array and then have your base activity have a getData() call that you can override in your derived activities that will supply the data that the Adapter so that the listview will then draw the appropriate items in the navdrawer. You will then have to implement the onItemClick event for each listview per activity.