I havd an Activity which has a TextView and i wanted to add a navigation drawer to that Activity. So I changed my XML and implemented DrawerLayout.
After implementing the DrawerLayout it simply does not functioning(meaning it don't open) and the FrameLayout implemented within the DrawerLayout blocks the not related to the DrawerLayout TextView text.
drawer.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.dl.master.lyrics.lyricsmaster.LyricsActivity"
android:id="#+id/drawer_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- The main content view where fragments are loaded -->
<FrameLayout
android:id="#+id/frame_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="#+id/text_tv_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- The navigation drawer -->
<TextView
android:layout_width="220dp"
android:layout_height="match_parent"
android:text="Try me! NOW"
/>
</android.support.v4.widget.DrawerLayout>
<!--
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text_tv_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
-->
The TextView inside the LinearLayout is the not related DrawerLayout widgets which cannot be seen. And the other TextView is the navigation drawer TextView. I know the navigation drawer widget has to have android:layout_gravity="start" property but it apparently has no layout parent so AS does not let me write it.
When running the Activity i see the text "Try it NOW" of the navigation drawer TextView and that's all.
DrawerActivity.java:
public class LyricsActivity extends AppCompatActivity
{
private TextView text;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle actionBarDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer);
this.initializeViews();
this.actionBarDrawerToggle = new ActionBarDrawerToggle(LyricsActivity.this,this.drawerLayout,
null,R.string.open_drawer_description,R.string.close_drawer_description);
this.drawerLayout.addDrawerListener(actionBarDrawerToggle);
//this.drawerLayout.openDrawer(GravityCompat.START); // java.lang.IllegalArgumentException: No drawer view found with gravity LEFT
}
#Override
protected void onResume()
{
super.onResume();
this.text.setText(getIntent().getStringExtra("Tags"));
}
/**
* Initialize all my views.
*
*/
public void initializeViews()
{
this.lyrics = (TextView) findViewById(R.id.text_tv_id);
this.drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout_id);
}
I read all the documentation and a lot of SO post and nothing helped me nor addressed this kind of problem.
DrawerLayout determines which Views to use as a drawers by their layout_gravity attribute. Simply add this attribute to your TextView with the appropriate value. For example:
<!-- The navigation drawer -->
<TextView
android:layout_width="220dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:text="Try me! NOW"
/>
Related
I have a drawer layout in which a scroll view is located. Both have layout_height="match_parent".
I commit a fragment transaction that replaces the scroll view by a linear layout (fragment_transaction.replace(R.id.scrollView, fragment_seals); ).
This linear layout also has layout_height="match_parent".
However, the linear layout's height doesn't match its parent's height (the drawer layout, since it replaces the scroll view which is the child of the drawer layout). Do you know why?
The drawer layout is the root.
The drawer layout correctly matches its "parent" (the viewport / screen of the device), I checked it out. But the linear layout just wraps its own content, I'm sure at 100%.
Sources
The linear layout of the fragment that replaces the scroll view
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/seals_main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorRichYellow"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="#+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/choose_seal" />
<ListView
android:id="#+id/handle_publication_share_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp" />
</LinearLayout>
The layout of the activity that makes the commit of the fragment transition, replacing its scroll view by the linear layout
<!-- Use DrawerLayout as root container for activity -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ScrollView>
<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemBackground="#color/color_states_menu"
app:menu="#menu/drawer_view">
<ImageView
android:id="#+id/logo_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_gravity="bottom"
android:src="#drawable/baseline_share_black_18dp"
android:background="#color/colorRoyalRedLight"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/constraint_layout_bottom"/>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
The fragment transition
public class ActivityHandlingFragments extends AppCompatActivity {
// <!------------------------------------------ BEGINNING - Defining fragments instances -->
SealsFragment fragment_seals = new SealsFragment();
// <!------------------------------------------ END - Defining fragments instances -->
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handling_fragments);
final FragmentManager fragment_manager = getSupportFragmentManager();
FragmentTransaction fragment_transaction = fragment_manager.beginTransaction(); // When app starts
fragment_transaction.replace(R.id.scrollView, fragment_home);
fragment_transaction.commit();
NavigationView navigation_view = (NavigationView) findViewById(R.id.navigation_view);
navigation_view.getMenu().getItem(0).setCheckable(true);
navigation_view.getMenu().getItem(0).setChecked(true);
final DrawerLayout drawer_layout = findViewById(R.id.drawer_layout);
navigation_view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
item.setChecked(true);
drawer_layout.closeDrawers();
// <!-------------------------------------- BEGINNING - NavigationView's routing -->
FragmentTransaction fragment_transaction = fragment_manager.beginTransaction();
switch(item.getItemId()) {
case R.id.menu_item_home_page:
case R.id.menu_item_my_seals:
fragment_transaction.replace(R.id.scrollView, fragment_seals);
break;
}
fragment_transaction.addToBackStack(null);
fragment_transaction.commit();
// <!-------------------------------------------- END - NavigationView's routing -->
return true;
}
});
}
So for some unknown reason (I've also searched around, checked if I wasn't typing the wrong ID or calling it before setting the view), the call findViewById returns null when I try to get the list view of a navigation drawer. I'm also currently following this tutorial, on the section "Inicialize the drawer list".
However, once I call the findViewById, I get a null reference, which later causes a null reference exception when I call the setAdapter method.
So here's the code in question:
public class DrawerActivity extends AppCompatActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks, AndroidFragmentApplication.Callbacks {
[Needless stuff here]
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private ListView mDrawerList;
private String[] mListItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer);
mListItems = getResources().getStringArray(R.array.list_values);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer_list); //this returns null
//null pointer exception happens next
mDrawerList.setAdapter(
new ArrayAdapter<>(
this, R.layout.drawer_list_item, mListItems
)
);
[More following, but it isn't needed]
And here goes the drawer_activity.xml:
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<!-- placed here as explained #
http://developer.android.com/training/appbar/setting-up.html-->
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:theme="#style/AppTheme.AppBarOverlay"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="pt.bluecover.wearable3d.DrawerActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!--
This here is the spin bar indicating that the program is loading something
-->
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dip"
android:layout_marginRight="100dip"
android:maxHeight="35dip"
android:minHeight="35dip"
android:minWidth="7dip"
android:maxWidth="7dip"
android:background="#android:color/transparent"
android:layout_centerHorizontal="true"
android:indeterminate="true" />
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment
android:id="#+id/navigation_drawer"
android:name="pt.bluecover.wearable3d.NavigationDrawerFragment"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
tools:layout="#layout/drawer_drawer" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
And the drawer_drawer.xml:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="#style/AppTheme.NavigationDrawer"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_list"
android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
tools:context="pt.bluecover.wearable3d.NavigationDrawerFragment" />
So, what may be causing said method to return null?
Following line and all listview realted code must be in NavigationDrawerFragment not in Activity
mDrawerList = (ListView) findViewById(R.id.drawer_list);
I am having an sliding drawer opening from right to left navigation when i touch the drawer icon on action bar. Working fine and closing on toggling the icon. no problem
I followed http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
In the sliding layout I have one small icon vibrate_ON.png.
Now i want when i touch the image in the sliding menu it will be changed to vibrate_OFF and so on toggling, keeping the sliding menu open.
how to do that?
You could do something like:
vibrateImageOn.setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
vibrateImageOff.setVisibility(View.Visible);
vibrateImageOn.setVisibility(View.GONE);
}
});
vibrateImageOff.setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
vibrateImageOn.setVisibility(View.Visible);
vibrateImageOff.setVisibility(View.GONE);
}
});
Assuming you load them both into ImageViews and they have equal positions, then this should work. Though, it is a bit messy..
You can put a layout in sliding menu for more controls. To do that, you must do some step:
1) Layout:
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f4f4f4" />
<!-- The navigation drawer -->
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="220dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#fff">
<!-- you can set any layout here -->
<TextView
android:id="#+id/tv_word"
android:text="New words"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:layout_width="210dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
2) Handle Event (plz don't forget closeDrawer)
DrawerLayout mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.linearLayout);
TextView tv_word = (TextView )findViewById(R.id.tv_word );
tv_word.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mDrawerLayout.closeDrawer(linearLayout);//don't forget it
//.....
}
});
Yet, when the button is placed in the hierarchy so that it can be seen on top of the navigation drawer, the button functions properly. However, the button should be hidden behind the navigation drawer when it is slid out, so this is not desirable.
Below is the code from MainActivity.java
public class MainActivity extends ActionBarActivity implements NavigationDrawerCallbacks {
public ProgressDialog progBar;
public final static boolean DEBUG = false;
public final static String TAG = "AppGetter";
private Toolbar mToolbar;
private NavigationDrawerFragment mNavigationDrawerFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mNavigationDrawerFragment = (NavigationDrawerFragment) getFragmentManager().findFragmentById(R.id.fragment_drawer);
mNavigationDrawerFragment.setup(R.id.fragment_drawer, (DrawerLayout) findViewById(R.id.drawer), mToolbar);
ImageButton cart_button = (ImageButton) findViewById(R.id.button2);
cart_button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
start_request();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public void onNavigationDrawerItemSelected(int position) {
Toast.makeText(this, "Menu item selected -> " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onBackPressed() {
if (mNavigationDrawerFragment.isDrawerOpen())
mNavigationDrawerFragment.closeDrawer();
else
super.onBackPressed();
}
public void start_request()
{
String pkg = getPackageName();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName(pkg,pkg+".RequestActivity"));
startActivity(intent);
if(DEBUG)Log.v(TAG,"Intent intent: "+intent);
}
}
I am assuming the issue lies within the class above, but for completion's sake, I pasted the two XML files of interest below.
activity_main.xml As you can see, the ImageButton is currently "above" the navigation drawer in hierarchy so as to make it be covered by the navigation drawer. Moving the ImageButton "below" makes the button work properly, but causes it to appear on top of the navigation drawer (and not tinted like the rest of the layout).
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:fontify="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:background="#color/myPrimaryColor">
<View
android:id="#+id/block1"
android:layout_height="240dp"
android:layout_width="match_parent"
android:layout_below="#+id/toolbar_actionbar"
android:background="#drawable/block_primary"
/>
<TextView
android:id="#+id/title1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_below="#+id/toolbar_actionbar"
android:layout_centerHorizontal="true"
android:layout_marginTop="56dp"
android:text="#string/title"
android:textColor="#color/white"
android:textSize="34sp"
android:fontFamily="sans-serif"
/>
<include
android:id="#+id/toolbar_actionbar"
layout="#layout/toolbar_default"
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<ImageButton
android:id="#+id/button2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="268dp"
android:src="#drawable/ic_chevron_up"
android:background="#drawable/fab_simple"/>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_below="#+id/toolbar_actionbar"
>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<fragment
android:id="#+id/fragment_drawer"
android:name="com.onepersonco.iconrequestbase.NavigationDrawerFragment"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
layout="#layout/fragment_navigation_drawer"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
fragment_navigation_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<!-- Provides a margin at the top of the navigation drawer. -->
<View
android:id="#+id/navWhiteSpace1"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="#color/myNavigationDrawerBackgroundColor"
/>
<android.support.v7.widget.RecyclerView
android:id="#+id/drawerList"
android:layout_below="#+id/navWhiteSpace1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:scrollbars="vertical"
android:scrollbarDefaultDelayBeforeFade="0"
android:scrollbarFadeDuration="0"
android:overScrollMode="never"
android:focusable="true"
android:background="#color/myNavigationDrawerBackgroundColor"/>
</RelativeLayout>
I ran into the same issue when attempting to follow various navigation drawer tutorials online.
What worked for me was using Mike Penz's MaterialDrawer library on GitHub. He has a very simple tutorial in the "readme" file found on the bottom of the page.
Hopefully someone else with a better understanding of Java can explain why your code failed.
I have a drawer layout with drawer on left.
Drawer has a button on click of which I want to replace the view of the drawer with a new view. The problem is , when new view gets replaced it doesn’t occupy the entire screen height.
To illustrate I have given a background colour to my navigation drawer views.
I want the Green view to occupy the entire screen height. Copy-paste the code below to get going:
MainActivity.java
public class MainActivity extends Activity {
LayoutInflater inflater;
DrawerLayout drawer;
RelativeLayout parentRL;
RelativeLayout viewToBeRemovedRL;
View viewToBeAdded;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main_activity);
inflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
parentRL = (RelativeLayout) findViewById(R.id.parentRL);
viewToBeRemovedRL = (RelativeLayout) findViewById(R.id.viewToBeReplaced);
}
public void onRemoveView(View view) {
viewToBeAdded = inflater.inflate(R.layout.add_view, null);
viewToBeRemovedRL.setVisibility(View.GONE);
parentRL.addView(viewToBeAdded);
}
public void onOpenDrawer(View view) {
drawer.openDrawer(parentRL);
}
}
main_activity.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" >
<RelativeLayout
android:id="#+id/leftRL"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="75dp"
android:onClick="onOpenDrawer"
android:text="Open Drawer" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/parentRL"
android:layout_width="290dp"
android:layout_height="match_parent"
android:layout_gravity="left" >
<RelativeLayout
android:id="#+id/viewToBeReplaced"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000" >
<Button
android:layout_width="100dp"
android:layout_height="75dp"
android:onClick="onRemoveView"
android:text="Change View" />
</RelativeLayout>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
add_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="290dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#00FF00" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="New view"
/>
</RelativeLayout>
Usually when this happens, the drawer actually DOES occupy the entire screen height, it's just that the default background colour of the view is clear.
Set you RelativeLayout#id/parentRL 's background to a solid colour or some drawable, e.g.
android:background="#android:color/black"
and your drawer should cover the entire screen height.