I'm attempting to implement a Navigation Drawer within an app I'm trying to create. Currently, the content of each Activity is being displayed within a Fragment. Since I can't use a static <fragment /> within the layout, I opted to use a dummy <FrameLayout /> instead. Here is my layout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout_messages"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Main content view -->
<FrameLayout
android:id="#+id/messages_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Drawer view -->
<ListView
android:id="#+id/messages_drawer_list"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#F0F0F0"/>
</android.support.v4.widget.DrawerLayout>
Now, when trying to replace the <FrameLayout /> with a fragment, I guess this error:
java.lang.IllegalStateException: The specified child already has a
parent. You must call removeView() on the child's parent first.
This is the code I'm executing in order to add in the fragment:
public class MessagesActivity extends Activity {
public static final String TAG = Constants.PACKAGE + ".MessagesActivity";
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle drawerToggle;
private ListView drawerItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "Starting activity: " + TAG);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout_messages);
String[] drawerItemsList = getResources().getStringArray(R.array.drawer_items);
drawerItems = (ListView) findViewById(R.id.messages_drawer_list);
drawerItems.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, drawerItemsList));
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.title_app, R.string.title_messages) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(R.string.title_messages);
invalidateOptionsMenu();
}
public void onDrawerOpened(View view) {
getActionBar().setTitle(R.string.title_app);
invalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(drawerToggle);
if (savedInstanceState == null) {
Log.d(TAG, "Setting fragment");
setFragment(0);
}
Log.d(TAG, TAG + "'s layout is initialized. Now starting service connection");
}
public void setFragment(int position) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.messages_content, new MessagesFragment());
transaction.addToBackStack(null);
transaction.commit();
drawerItems.setItemChecked(position, true);
drawerLayout.closeDrawer(drawerItems);
}
}
That Activity file is basically pulled directly from Google's developer resources, yet I'm still getting an error message. Am I forgetting to do something?
EDIT: Added my MessagesFragment code for you all.
public class MessagesFragment extends Fragment {
public MessagesFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_messages, container);
}
}
return inflater.inflate(R.layout.fragment_messages, null);
Could you please try and use null instead of container.
Related
I have read a lot of answers here but could not manage to do it. I want all of my activities to have a drawer. Inside the drawer i have a ListView which contains all of the activities that the drawer should open. This is the implementation of the drawer:
public abstract class DrawerActivity extends BaseActivity {
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.base_drawer_layout);
drawerLayout = findViewById(R.id.drawer_layout);
drawerList = findViewById(R.id.left_drawer);
final ArrayList<String> elements = new ArrayList<>();
elements.add("My tasks");
elements.add("Issues");
drawerList.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, elements));
drawerList.setOnItemClickListener(createOnDrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
drawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view)
{
getSupportActionBar().setTitle("TITLE");
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView)
{
getSupportActionBar().setTitle("Title");
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
drawerLayout.addDrawerListener(drawerToggle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggles
drawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (drawerToggle.onOptionsItemSelected(item))
return true;
return super.onOptionsItemSelected(item);
}
protected abstract DrawerItemClickListener createOnDrawerItemClickListener();
protected ListView drawerList()
{
return drawerList;
}
protected DrawerLayout drawerLayout()
{
return drawerLayout;
}
}
This is the drawer layout xml file
<?xml version="1.0" encoding="utf-8"?>
<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">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#274"/>
</android.support.v4.widget.DrawerLayout>
Lets say i have currently two activities, My Tasks and Issues and both of them extend DrawerActivity. If i am in the Issues activity, how can i open the My Tasks activity through that drawer?
All activities that extend DrawerActivity implements createOnDrawerItemClickListener() which inside creates a new fragment with the layout of the the activity that implements DrawerActivity, which i'm pretty sure is wrong.
Example implementation:
#Override
protected DrawerItemClickListener createOnDrawerItemClickListener()
{
return new DrawerItemClickListener(position ->
{
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, new TaskFragment()).commit();
drawerList().setItemChecked(position, true);
drawerLayout().closeDrawer(drawerList());
});
}
And the DrawerItemClickListener:
public class DrawerItemClickListener implements ListView.OnItemClickListener {
private FragmentStrategy fragmentStrategy;
public DrawerItemClickListener(final FragmentStrategy fragmentStrategy)
{
this.fragmentStrategy = fragmentStrategy;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
fragmentStrategy.showFragment(position);
}
public interface FragmentStrategy {
void showFragment(final int position);
}
}
How can i make this work?
In your case adding fragment will be the best solution.
create a fragment BlankFragment.java
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
and create fragment_black.xml
<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"
tools:context="com.above_inc.shyam.drawer.BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
now replace your method
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_camera) {
// Handle the camera action
fragment = new BlankFragment();
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
add below code in your content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.above_inc.shyam.drawer.MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
you can also add more fragment to other options same as camera in above code
I'm able to click the tabs to change, but nothing happens when I swipe. I don't see the coloured bar underneath the selected tab either.
Here's my code. I've largely followed this tutorial, but I've changed tabLayout.setOnTabSelectedListener(this) to tabLayout.addOnTabSelectedListener(this) in StoriesActivity because the former is depreceated.
StoriesActivity:
public class StoriesActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
//This is our tablayout
private TabLayout tabLayout;
//This is our viewPager
private ViewPager viewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stories);
/* +++ START Intent +++ */
Bundle extras = getIntent().getExtras();
final int authorID = extras.getInt("author_id");
final String authorName = extras.getString("author_name");
Log.i("click", Integer.toString(authorID));
/* +++ END Intent +++ */
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(authorName);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
//Initializing the tablayout
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Stories"));
tabLayout.addTab(tabLayout.newTab().setText("Collections"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//Initializing viewPager
viewPager = (ViewPager) findViewById(R.id.pager);
//Creating our pager adapter
StoriesTabsAdapter adapter = new StoriesTabsAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
//Adding adapter to pager
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
//Adding onTabSelectedListener to swipe views
tabLayout.addOnTabSelectedListener(this);
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
activity_stories.xml:
<RelativeLayout
android:id="#+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
app:navigationIcon="?attr/homeAsUpIndicator"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/stories_list_view" />
</RelativeLayout>
StoriesTabsAdapter:
public class StoriesTabsAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
public StoriesTabsAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
StoriesFragment tab1 = new StoriesFragment();
return tab1;
case 1:
CollectionsFragment tab2 = new CollectionsFragment();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
StoriesFragment:
public class StoriesFragment extends Fragment {
public StoriesFragment() {
// Required empty public constructor
}
private ListView storiesListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_stories, container, false);
}
}
You are missing to setupWithViewPager your TabLayout.
mTabLayout.setupWithViewPager(mViewPager)
Regarding the problem of your text not to be appearing, try to move the code below straight after you setupWithViewPager
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Stories"));
tabLayout.addTab(tabLayout.newTab().setText("Collections"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
You should follow below two points.
Use FragmentStatePagerAdapter for good approach.
setupWithViewPager
If you're using a ViewPager together with this layout, you can call
setupWithViewPager(ViewPager) to link the two together. This layout
will be automatically populated from the PagerAdapter's page titles.
Secondly
_tablayoutOBJ.setupWithViewPager(_viewpagerOBJ); // After addOnTabSelectedListener .
For, Demo case you can visit Material Design working with Tabs.
I need to customize my navigation drawer like following.
Currently I was able to add following part.
No matter how hard I tried to add another text fields, edit texts and images, I couldn't do it.
Here is my sample code.
This is how I added fields in strings.xml
<string-array name="titles">
<item>Hotel</item>
<item>Historical Sites</item>
<item>Shopping</item>
<item>Restaurant</item>
<item>Attractions</item>
<item>wild Life</item>
<item>Tour Service</item>
</string-array>
<array name="icons">
<item>#drawable/ic_hotel</item>
<item>#drawable/ic_historical</item>
<item>#drawable/ic_shopping</item>
<item>#drawable/ic_resturant</item>
<item>#drawable/ic_attraction</item>
<item>#drawable/ic_wildlife</item>
<item>#drawable/ic_tourservices</item>
</array>
Here is my mainactivity.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">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<!-- Listview to display slider menu -->
<include layout="#layout/drawer_layout" />
Here is my list_item.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="48dp"
android:padding="5dp" >
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
/>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_toRightOf="#id/icon"
android:gravity="center_vertical"
android:textColor="#ffffff"
android:textSize="20sp" />
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"/>
</RelativeLayout>
Here is my CustomAdapter.java
public class CustomAdapter extends BaseAdapter {
Context context; List<RowItem> rowItem;
CustomAdapter(Context context, List<RowItem> rowItem) {
this.context = context;
this.rowItem = rowItem;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item, null);
}
ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon);
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
RowItem row_pos = rowItem.get(position);
// setting the image resource and title
imgIcon.setImageResource(row_pos.getIcon());
txtTitle.setText(row_pos.getTitle());
return convertView;
}
#Override
public int getCount() {
return rowItem.size();
}
#Override
public Object getItem(int position) {
return rowItem.get(position);
}
#Override
public long getItemId(int position) {
return rowItem.indexOf(getItem(position));
}
}
Here is my mainactivity.java
public class Extract extends ActionBarActivity {
String[] menutitles;
TypedArray menuIcons;
// nav drawer title
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private List<RowItem> rowItems;
private CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_extract);
mTitle = mDrawerTitle = getTitle();
menutitles = getResources().getStringArray(R.array.titles);
menuIcons = getResources().obtainTypedArray(R.array.icons);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.slider_list);
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < menutitles.length; i++) {
RowItem items = new RowItem(menutitles[i], menuIcons.getResourceId( i, -1));
rowItems.add(items);
}
menuIcons.recycle();
adapter = new CustomAdapter(getApplicationContext(), rowItems);
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new SlideitemListener());
// enabling action bar app icon and behaving it as toggle button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,R.drawable.ic_menu, R.string.app_name,R.string.app_name)
{
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(mTitle);
// calling onPrepareOptionsMenu() to show action bar icons
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(mDrawerTitle);
// calling onPrepareOptionsMenu() to hide action bar icons
invalidateOptionsMenu(); }
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
// on first time display view for first nav item
updateDisplay(0);
}
}
class SlideitemListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
updateDisplay(position);
}
}
private void updateDisplay(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MapFragment();
break;
case 1:
fragment = new hotel();
break;
case 2:
fragment = new restaurant();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
setTitle(menutitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
else {
// error in creating fragment
Log.e("Extract", "Error in creating fragment");
}
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getSupportActionBar().setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_extract, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.action_settings:
return true;
default :
return super.onOptionsItemSelected(item);
}
}
/*** * Called when invalidateOptionsMenu() is triggered */
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
/** * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()... */
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState(); }
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggles
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
Here is my drawer_layoout.xml
<?xml version="1.0" encoding="utf-8"?>
<DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/slider_list"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#000000"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:layout_weight="1" />
</DrawerLayout>
Please help me to add the image, two text views near image, horizontal line, and the edit text. Thanks in advance
In your MainActivity, add a new field for the LinearLayout, and assign value to it in onCreate()
private LinearLayout mLenear;
mLenear = (LinearLayout)findViewById(R.id.left_drawer);// inside onCreate
Then add following code inside onPrepareOptionsMenu
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mLenear);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
Then change your closeDrawer like this.
mDrawerLayout.closeDrawer(mLenear);
This should resolve your issue. :)
this will be the main layout that you will be using it contain two parts one is the main part which will have the layout of the main screen and the drawer_layout is the layout that has you navigation view layouts
So you will have to create drawer_layout as you want to display and just simply call it here
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/navigationDrawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
// you will have layout that you will use for your main activity or the activity where you are showing your navigation View
</FrameLayout>
// the drawer_layout will define your navigation View
<include layout="#layout/drawer_layout" />
</android.support.v4.widget.DrawerLayout>
In the activity you will get access to your drawer_layout and get access to your views using that object like
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.navigationDrawer);
// Example of getting your view object
ImageView yourImageView = (ImageView) drawerLayout.findViewById(R.id.imageView);
// you can access any your drawerView using that drawerLayout object
I've some problems with the drawer navigation. I've tried much and googled a lot but didn't find a solution.
I'm using a drawer navigation. There you have to fill it's frame layout with fragments.
That works fine, so for example:
I pick something in the drawer navigation and it's frame layout loads the fragment (startdisplay in my app) with buttons and textviews.
Now I click on one of the fragments buttons, this should call the actionlistener in the fragments java class (startdisplay.java), but instead it's not finding these actionlisteners (android studio also tells me that these are never used). I found out that the app is looking in the drawer navigation class (mainmenuactivity in my app).
My question is if there is a way that my app is looking directly in the fragments java class, because I can't put all my code in one class (mainmenuactivity). Of course this won't be my only fragment that I'd have to put in there.
Here is the code:
The XML of the Startdisplay Fragment:
<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"
tools:context="de.touristenfahrerforum.MarcelMoiser.Fragments.Startdisplay">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="#+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="114dp"
android:onClick="startButton"
android:text="Start"
android:textSize="50sp" />
....
The java class of the Startdisplay fragment:
public class Startdisplay extends Fragment
{
....
private Activity activity;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_startdisplay, container, false);
loadTrackText = (TextView)view.findViewById(R.id.loadTrackText);
loadModeText = (TextView)view.findViewById(R.id.loadModeText);
loadBestlapText = (TextView)view.findViewById(R.id.loadBestlapText);
fileService = new Fileservice();
activity = this.getActivity();
return view;
}
....
/**
* Actionlistener für den Start Button
*/
public void startButton(View view) //!!!!!!!!!!!!!!This method should be called when the button is pressed <-------------------------------------------------------------
{
if(track != null)
{
if( ((LocationManager) activity.getSystemService(activity.LOCATION_SERVICE)).isProviderEnabled(LocationManager.GPS_PROVIDER))
{//GPS ist aktiviert
Intent intent = new Intent(activity, MainActivity.class);
intent.putExtra(V.TRACK_EXTRA, track); //Hier könnte man vll auch nur den String statt dem Objekt übergeben <------
intent.putExtra(V.MODE_EXTRA, mode);
intent.putExtra(V.BESTLAP_EXTRA, bestlap);
startActivity(intent);
}
else{}//Meldung geben das das GPS nicht aktiviert ist
}
else{}//else es muss erst eine Strecke geladen werden
}
....
The Mainmenu XML (Drawer Layout):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_menu"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111" />
</android.support.v4.widget.DrawerLayout>
And the Mainmenuactivity(where the app searches for the startButton actionlistener):
public class MainMenuActivity extends Activity
{
private String[] menuItems;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private CharSequence mTitle;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
//Standartwerte für die Einstellungen erzeugen
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
mTitle = getTitle();
menuItems = new String[]{"Peter","Susi","Elephant"};
mDrawerLayout = (DrawerLayout) findViewById(R.id.main_menu);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
//Holt sich den Wert für die Umrechnung zwischen PX und DP
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
V.LOGICAL_DENSITY = metrics.density;
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, menuItems));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
selectItem(position);
}
}
/** Swaps fragments in the main content view */
private void selectItem(int position)
{
// Create a new fragment and specify the planet to show based on position
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new Startdisplay())
.commit();
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(menuItems[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title)
{
mTitle = title;
getActionBar().setTitle(mTitle);
}
}
I'm only testing, so the menuItems have no sense and it's always loading the Startdisplay fragment, whatever I click on. So like I already said, the app should use the actionlistener in the Startdisplay.java and should not search for it in the MainMenuActivity.java.
Thanks in advance
Your problem is that when you set the attribute android:onClick, the method is looked for in the context of this view. The context of the view is, of course, the activity and not the fragment, which is why Android can't find your method there. So you have two options:
Put the method into the activity and delegate to the fragment.
Use View.OnClickListener instead.
In general I personally don't really like using android:onClick anyway because it is very easy to break. If it doesn't work, it just silently fails, like in your case. Therefore, I would use the second way.
Call something like this in onCreateView() of the fragment:
view.findViewById(R.id.startButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do what you need
}
});
First of all excuse my stupid knowledge of android, because I'm new in it.
We have some codes here that changes tabs with swipe gesture with 3 Fragments that named: "Top Rated", "Games", "Movies".
This is the source codes
Here is MainActivity activity:
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Top Rated", "Games", "Movies" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
With this adapter
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
This is main xml:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
One of Fragments (others are like this)
public class GamesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_games, container, false);
return rootView;
}
}
With this 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"
android:background="#ff8400" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Design Games Screen"
android:textSize="20dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
Now we want to add a button in this page see this 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"
android:background="#ff8400" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Design Games Screen"
android:textSize="20dp"
android:layout_centerInParent="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
One way to do this is define button and listener in GamesFragment.java
that is impossible, because it can't be define in that class.
final Button button = (Button) findViewById(R.id.button);
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// do some thing
}
});
Second way is merge GameFragment java codes with main codes. And edit main activity like this:
setContentView(R.layout.activity_main & R.layout.fragment_games);
That I can't write codes correctly.
Third way is we should write our fragments in main activity that use one layout.
Now can u help me to solve this?
final Button button = (Button) rootView.findViewById(R.id.button);
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// How to start a new activity form here?????
}
});
This worked quite well.