The fragment I'm having problems with is using a CardListView from the Cardslib library. I added the fragment dynamically to the container and everything is working as expected, except it isn't responding when it is interacted with. This means it doesn't scroll, I can't press on any of the cards, and anything else related to the problem.
Adding fragment to container in MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
// Code here...
NoteFragment nf = new NoteFragment();
// nf.setArguments(getIntent().getExtras());
FragmentTransaction tx = getFragmentManager().beginTransaction();
tx.add(R.id.container, nf);
tx.commit();
}
Replaces container fragment when Navigation Drawer is used in MainActivity. Default case selected is NoteFragment.
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch(position) {
case 0:
onSectionAttached(0);
fragment = new NoteFragment();
break;
case 1:
onSectionAttached(1);
fragment = new ArchiveFragment();
break;
case 2:
onSectionAttached(2);
fragment = new TrashFragment();
break;
}
FragmentTransaction tx = getFragmentManager().beginTransaction();
tx.replace(R.id.container, fragment);
tx.commit();
}
NoteFragment returning inflated layout:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// CardListView Code Here...
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_note, container, false);
}
Container XML (activity_main.xml):
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- 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" />
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="com.example.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
Fragment XML (fragment_note.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=".fragments.NoteFragment">
<it.gmariotti.cardslib.library.view.CardListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:id="#+id/CardList"/>
</FrameLayout>
Any help is appreciated.
I fixed it! The Cardslib piece of code in onCreateView() was moved to onStart(), and it fixed the unresponsiveness.
Related
I'm using a navigation drawer along with a SwipeRefreshLayout for the main content and when the user selects a menu item in the navigation drawer, I want to replace the fragment inside the SwipeRefreshLayout with another fragment.
This is what my onNavigationItemSelected() looks like:
// Handle navigation view item clicks here.
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
selectedNavItem = item.getItemId();
if(selectedNavItem == R.id.nav_files){
filesFragment = new FilesFragment();
fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.swipeLayout,filesFragment,"files");
transaction.commit();
} else if(selectedNavItem == R.id.nav_accounts){
accountsFragment = new AccountsFragment();
fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.swipeLayout,accountsFragment,"accounts");
transaction.commit();
}
return true;
But this never works. When I click an item in the nav drawer, the fragment is replaced by a blank screen. My onCreate method also uses FragmentTransaction.replace() but that seems to work fine.
I also tried FragmentTransaction.remove() and then FragmentTransaction.add() but even that doesn't seem to work.
Edit: Layout files:
Layout of the content view of the navigation drawer:
<android.support.v4.widget.SwipeRefreshLayout
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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.harshallele.cloudpool.MainActivity"
tools:showIn="#layout/app_bar_main"
android:id="#+id/swipeLayout">
</android.support.v4.widget.SwipeRefreshLayout>
This is included inside another layout file which contains a CoordinatorLayout containing the toolbar.That file, in turn, is inside the main layout file of the activity inside a android.support.v4.widget.DrawerLayout
(Basically, this is the Navigation Drawer Activity provided by Android Studio when adding an Activity)
Layout for FilesFragment:
<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=".fragments.FilesFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/fileListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
/>
<ProgressBar
android:id="#+id/itemsLoadingProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminateOnly="true"
android:visibility="invisible"
/>
</FrameLayout>
Layout for AccountsFragment(this is just the default blank fragment, because i haven't finished this yet):
<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.harshallele.cloudpool.fragments.AccountsFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
Edit 2:
AccountsFragment:
public class AccountsFragment extends Fragment {
public AccountsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_accounts, container, false);
}
}
With just this bit of code we can't help you so much. The problem can be that:
The FilesFragment and AccountsFragment aren't initialized in the right way;
The Layout with id swipeLayout can have visibility = gone;
The Layout of FilesFragment and AccountsFragment can be empty;
This are just some of the infinite reason why your code doesn't work properly so please share more code about the two Fragments and relative XML.
I'm creating a layout which contains a maps (com.google.android.gms.maps.SupportMapFragment) & a mini layout to enter origin & destination(pickup_dropoff_LL LinearLayout).
XML
<RelativeLayout
android:id="#+id/main_RL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rideType_LL">
<include
android:id="#+id/pickup_dropoff_LL"
layout="#layout/layout_pickup_dropoff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp" />
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
</RelativeLayout>
Initially this had a corresponding Activity but I had to introduce a DrawerLayout so I had to convert it to a Fragment.
After doing that my pickup_dropoff_LL disappears.
It is shown on the screen for a micro second and then it disappears.
I suspect the issue is somewhere here but I'm not sure.
SupportMapFragment fm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_main_activity, container, false);
fm = new SupportMapFragment() {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
map = fm.getMap();
if (map != null) {
map.setMyLocationEnabled(true);
fm.getMapAsync(MainActivity2.this);
}
}
};
getChildFragmentManager().beginTransaction().add(R.id.main_RL, fm).commit();
return rootView;
}
1. I checked visibility for pickup_dropoff_LL. It's showing as 0, which means View.VISIBLE. But it is not visible.
2. As suggested by some links, I tried placing an empty view of same height & width over my map. Even that didn't work.
So how do I stop the view from disappearing?? Please help.
Try drawing your layout last. Put the Include after the Fragment
<RelativeLayout
android:id="#+id/main_RL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rideType_LL">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
<include
android:id="#+id/pickup_dropoff_LL"
layout="#layout/layout_pickup_dropoff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp" />
</RelativeLayout>
Have you tried moving your content inside of your drawer and not behind it?
<!-- Drawer Host inside the parent relative layout -->
<android.support.v4.widget.DrawerLayout
android:id="#+id/main_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Hold Fragment here -->
<FrameLayout
android:id="#+id/frag_main_host"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Drawer -->
<RelativeLayout
android:id="#+id/drawer_pane"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start">
<!-- Menu list for drawer -->
<ListView
android:id="#+id/menu_list"
android:layout_height="match_parent"
android:layout_width="280dp"
android:dividerHeight="1sp"
android:gravity="start"
android:choiceMode="singleChoice" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
Putting anything below your view would make it not appear when opened although it is visible in property. In your class you can swap the fragment as desired by calling the fragment manager and seleting a fragment at whatever list index is selected. I suggest use an internal listener and just call a method to pick the view and swap it. Like below:
Listener (Internal class):
class MainDrawerItemClickListener implements AdapterView.OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id ){
getView(position);
// close the drawers once selected
mDrawerLayout.closeDrawers();
}
}
That method will call this method in your main class:
// select the view
public void getView( int position ){
Fragment frag = null;
switch( position ){
case 0:
frag = new MyFragment();
break;
case 1:
frag = new MyOtherFragment();
break;
default:
break;
}
if( frag != null ){
swapView( frag );
}
}
// swaps the fragments
public void swapView( Fragment frag ){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace( R.id.frag_main_host, frag ).commit();
}
Hope it helps, I know this is an old question, but I am sure someone will have the same question.
i want to show a fragment when i click a item into my action bar, in code i do that:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.create_boundary:
Fragment boundary = new BoundaryFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.map_activity, boundary);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
break;
}
}
and the fragment:
public class BoundaryFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create the view of the fragment associate with the maps activity
View view = inflater.inflate(R.layout.boundary_maps, container, false);
return view;
}
fragment's layout:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</GridLayout>
activity_map.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map_activity"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
</RelativeLayout>
onCreate of mapsActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
[...]
}
i don't understand why is not shown.Can someone tell me what's is wrong?
thanks in advance.
As stated in the official documentation for FragmentTransaction.replace(int,Fragment,String):
Parameters
- containerViewId Identifier of the container whose
fragment(s) are to be replaced.
- fragment The new fragment to place in
the container.
- tag Optional tag name for the fragment, to later
retrieve the fragment with FragmentManager.findFragmentByTag(String).
That means you are using the id in the transaction incorrectly. Also you may want to add the BoundaryFragment on top of the one defined in the XML layout, therefore you should use FragmentTrasaction.add(int, Fragment) instead.
To fix your problem anyway you should move your id to the RelativeLayout, as below:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map_activity"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
</RelativeLayout>
First, you are using a Fragment as it would be a ViewGroup. You’re trying to place a Fragment inside another Fragment when you perform the next statement:
ft.replace(R.id.map_activity, boundary);
Second, you can’t replace a fragment that has been defined in the layout file. You can only replace fragments that you added dynamically using FragmentTransaction.
To achieve what you want, take a look at the sample code under the section:
"Or, programmatically add the fragment to an existing ViewGroup."
I have a Navigation Drawer and a ViewPagerIndicator inside the content_frame. I want to change between fragment`s from the navigation drawer but the problem is that switch between tabs ViewPager works but when I switch to another option that you have to remove the ViewPager and put a new fragment puts this fragment under the ViewPager.
Attached photo so you can see.
1) Here you can already see the new fragment below ViewPager.It can be distinguished by the text shown is Prueba
Attached code
Activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/content_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.viewpagerindicator.TabPageIndicator
android:id="#+id/indicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</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"/>
Method for switching between fragment.
/** Main content by replacing fragments
* #param position
*/
private void selectItem(int position) {
//Code
Fragment fragment = new TryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
switch (position) {
case 0:
mPager.setCurrentItem(0);
break;
case 1:
mPager.setCurrentItem(1);
break;
case 2:
ft.replace(R.id.content_frame, fragment);
break;
}
ft.commit();
mAdapter.notifyDataSetChanged();
//Close drawer
mDrawerLayout.closeDrawer(mDrawerList);
}
Class TryFragment
class TryFragment extends Fragment
{
public static final String ARG_PLANET_NUMBER = "planet_number";
public TryFragment()
{
// Empty constructor required for fragment subclasses
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
TextView text = new TextView(getActivity());
text.setGravity(Gravity.CENTER);
text.setText("Prueba");
text.setTextSize(20 * getResources().getDisplayMetrics().density);
text.setPadding(20, 20, 20, 20);
LinearLayout layout = new LinearLayout(getActivity());
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout.setGravity(Gravity.CENTER);
layout.addView(text);
Log.d("TestFragment", "Estoy en el fragment");
return layout;
}
}
I do not know if I have to destroy the viewpager to show the new fragment or a problem of hierarchy in the xml.
Your ViewPager must be Fragment, and it should be placed to layout.content_frame, so when you calling ft.replace(R.id.content_frame, fragment); your ViewPager fragment will be replaced.
You should not use ViewPager and NavigationDrawer at the same time. You can see Roman Nurik's answer in this G+ post:
https://plus.google.com/u/1/+DavidTaSmoochibi/posts/8dWEkFcbTFX
"You shouldn't use navigation drawers with action bar tabs. If you're aiming for a UI similar to that of Google Play Music, you should implement tabs manually (and beware of how this looks on tablet—you don't want full-width tab bars on tablets). Also make sure to check out the Structure in Android App Design session from this year's Google I/O for a detailed run-through of the various interface patterns available for exposing app hierarchy."
I am trying to show multiple fragments on the one screen by creating them programmatically. I am able to do this no problem by including each fragment into the activities layout file. However when I try and do it programmatically Im confused.This is what I have so far for two fragments on a screen.
Main Class:
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentOne one = new FragmentOne();
FragmentTwo two = new FragmentTwo();
FragmentThree three = new FragmentThree();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.imOne, one, "fragmentone");
ft.add(R.id.imTwo, two, "fragmenttwo");
ft.add(R.id.imThree, three, "fragmenthree");
ft.commit();
}
}
Fragment One:
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.frag_one, container, false);
return view;
}
}
Fragment Two:
public class FragmentTwo extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.frag_two, container, false);
return view;
}
}
The layout files for my two fragment classes just contain a simple TextView.
And then the activity_main.xml layout file for my main class:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/imOne"
android:name="com.david.twofragexample.FragmentOne"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<FrameLayout
android:id="#+id/imTwo"
android:name="com.david.twofragexample.FragmentTwo"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<FrameLayout
android:id="#+id/imThree"
android:name="com.david.twofragexample.FragmentThree"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
When I try and do it programatically I get confused as to what should be in my activity_main.xml file. So from the Android Developer Guide(http://developer.android.com/guide/components/fragments.html) it says to use
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
So when I add this code to my onCreate method what changes do I have to make to my activity_main.xml file to do this programmatically?I don't see where R.id.fragment_container comes from. How can I determine where on the screen my new fragment will go?Thanks
EDIT: I am developing this on a tablet and not a phone.This has now been solved and the above code will add three fragments programmatically.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/list"
android:name="com.david.twofragexample.FragmentOne"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<FrameLayout
android:id="#+id/viewer"
android:name="com.david.twofragexample.FragmentTwo"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
In your Activity:
FragmentOne one = new FragmentOne();
FragmentTwo two = new FragmentTwo();
fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.list, one, "fragmentone").commit();
fm.beginTransaction().replace(R.id.viewer, two, "fragmenttwo").commit();
I suggest you study this:
http://developer.android.com/reference/android/app/Fragment.html
and fully understand the fragment lifecycle, etc. The way I show is quick and dirty, but not neccesarilly best.
As I don't have higher enough reps to comment yet, I will just leave the information here -- the way Rafael T suggested does work nicely, although I also had my doubt at the first place.
1) Define your xml like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
2) Add each fragment into the same slot:
View box = v.findViewById(R.id.container);
FragmentTransaction ft = getFragmentManager().beginTransaction();
for (String catalog : mCatalogs) {
Fragment fragment = HighlightedProductFragment.newInstance(catalog);
ft.add(R.id.container, fragment, catalog);
}
ft.commit();
Thanks for the solution for this tricky requirement.
Try it like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
as your activity_main.xml
You asked yourself the right question: where is the id fragment_container, and the answer was: nowhere. >ou also set your layout to horizontal, which makes it very likely, that added Views will be kind of 'out of screen'