I'm doing an app that uses Google Maps APIs (with two separate maps), and I want to use a navigation drawer to switch between the two maps (fragments).
I created the main activity with the pre-compiled Navigation Drawer Activity in android studio, and here is the pieces of code:
The main activity uses this layout:
activity_main_activity2.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="it.radonmap.radonmap.MainActivity2">
<FrameLayout android:id="#+id/container" 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.SupportMapFragment" />
<fragment android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width" android:layout_height="match_parent"
android:layout_gravity="start" android:name="it.radonmap.radonmap.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
Here is the code which calls the .replace() method:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
//do something
break;
case 1:
fragment = new FragPunti();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager;
fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.containerPunti,fragment).commit();
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
FragPunti.java
public class FragPunti extends android.support.v4.app.Fragment {
public FragPunti(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.frag_punti, null);
return rootView;
}
}
frag_punti.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/containerPunti">
<FrameLayout
android:id="#+id/framePunti"
android:layout_width="0px"
android:layout_height="match_parent"
>
<TextView
android:id="#+id/txtLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="16dp"
android:text="Punti"/>
</FrameLayout>
</FrameLayout>
And here is the logcat trace:
04-30 19:17:45.823 20909-20909/it.radonmap.radonmap E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: it.radonmap.radonmap, PID: 20909
java.lang.IllegalArgumentException: No view found for id 0x7f090058 (it.radonmap.radonmap:id/containerPunti) for fragment FragPunti{36b6aaa5 #2 id=0x7f090058}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:945)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1499)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:456)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5274)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
I had already look for a solution but with no results.
Hope someone can help me.
You should pass id of container for fragment, and that's a view in which you want to show fragment. It is in activity, not in fragment you want to show. So change replace(R.id.containerPunti, fragment) to replace(R.id.container, fragment).
Related
I am making an app using this tutorial. I made some changes in my code, ie I wanted to get data from server to my main activity and pass it to my fragments. Before that , when I would open the app it worked perfectly, bu now it crashes. I have tried a bunch of answers from stackoverflow (1, 2, 3, 4, 5...) before asking a question, but none of them answered my question. When I was getting restaurants from fragment directly it worked perfectly but passing the data from the activity causes this error.
Main Activity (I pass get data from server and pass it to fragment):
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_map)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_list)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_my_list)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
RestaurantsFragment restaurantsFragment = new RestaurantsFragment();
Bundle args = new Bundle();
args.putParcelableArrayList("restaurantList", (ArrayList<? extends Parcelable>) restaurantList);
restaurantsFragment.setArguments(args);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.sliding_tabs, restaurantsFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Restaurant Fragment (I do get data from my main activity, I get the restaurants from the server when I debug):
public class RestaurantsFragment extends Fragment {
private static final String TAG = RestaurantsFragment.class.getSimpleName();
// Restaurants json url
private ProgressDialog pDialog;
private ArrayList restaurantList = new ArrayList<>();
private ListView listView;
private CustomListAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_restaurants, container, false);
Bundle bundle = this.getArguments();
if (bundle != null) {
restaurantList = bundle.getParcelableArrayList ("restaurantList");
}
listView = (ListView) view.findViewById(R.id.restaurants_list);
adapter = new CustomListAdapter(getActivity(), restaurantList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading...");
pDialog.show();
return view;
}
fragment_restaurants
<RelativeLayout 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=".sliderfragments.RestaurantsFragment">
<ListView
android:id="#+id/restaurants_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_row_selector" />
</RelativeLayout>
list_row
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_row_selector"
android:padding="8dp">
<!-- Thumbnail Image -->
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/thumbnail"
android:background="#drawable/default_profile"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentLeft="true"
android:layout_marginRight="8dp" />
<!-- User Name -->
<TextView
android:id="#+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:textSize="#dimen/userName"
android:textStyle="bold" />
<!-- Date -->
<TextView
android:id="#+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/userName"
android:layout_marginTop="1dip"
android:layout_toRightOf="#+id/thumbnail"
android:textSize="#dimen/date" />
<!-- Time -->
<TextView
android:id="#+id/time"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/date"
android:layout_marginTop="5dp"
android:layout_toRightOf="#+id/thumbnail"
android:textColor="#color/time"
android:textSize="#dimen/time" />
</RelativeLayout>
content_main
<?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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/app_bar_main">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
</android.support.design.widget.AppBarLayout>
Pager Adapter:
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
MapsFragment tab1 = new MapsFragment();
return tab1;
case 1:
RestaurantsFragment tab2 = new RestaurantsFragment();
return tab2;
case 2:
MyRestaurantsFragment tab3 = new MyRestaurantsFragment();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
Stack trace:
10-09 12:30:12.755 32374-32374/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.kemo.restaurant, PID: 32374
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.kemo.restaurant/com.test.kemo.restaurant.MainActivity}: java.lang.IllegalStateException: HorizontalScrollView can host only one direct child
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: HorizontalScrollView can host only one direct child
at android.widget.HorizontalScrollView.addView(HorizontalScrollView.java:216)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1174)
at android.app.Activity.performStart(Activity.java:5347)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
you are adding your fragment to your sliding tab view. you wrote :
fragmentTransaction.replace(R.id.sliding_tabs, restaurantsFragment);
tab layout is a child of horizontal scrollview see documentation: https://developer.android.com/reference/android/support/design/widget/TabLayout.html
i dont know how your application works but you cant add your fragment to TabLayout here cause it makes multiple children for that that is now allowed (TabLaout is actually a horizontal scrollView inside)
in fragmentTransaction.replace() method that i mentioned you must specify the container in which you want to add the fragment. from what your code says you are using the tabLayput for title of your viewpager not for replacing your fragment in it.
make a place (container) in your main activity in which you want to add your fragment in. absolutely its not in your R.id.sliding_tabs, beside your titles of viewpager.
I am trying to make navigation drawer using fragments using the reference link : https://guides.codepath.com/android/Fragment-Navigation-Drawer
But the problem is when i tap on any of the item in navigation drawer it does not replace the corresponding fragment to the main activity layout.
Main activity snippet:
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass;
switch(menuItem.getItemId()) {
case R.id.nav_first_fragment:
//fragmentClass = FirstFragment.class;
fragment=new FirstFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().add(R.id.flContent, fragment).commit();
break;
case R.id.nav_second_fragment:
//fragmentClass = SecondFragment.class;
fragment=new SecondFragment();
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.flContent, Fragment.instantiate(MainActivity.this, "com.example.FirstFragment"));
tx.commit();
break;
default:
fragmentClass = FirstFragment.class;
}
activity_main layout:
<!-- This LinearLayout represents the contents of the screen -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- The ActionBar displayed at the top -->
<include
layout="#layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- The main content view where fragments are loaded -->
<LinearLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
/>
</LinearLayout>
<!-- The navigation drawer that comes from the left -->
<!-- Note that `android:layout_gravity` needs to be set to 'start' -->
<android.support.design.widget.NavigationView
android:id="#+id/nvView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:headerLayout="#layout/nav_header"
android:layout_gravity="start"
android:background="#android:color/white"
app:menu="#menu/drawer_view" />
</android.support.v4.widget.DrawerLayout>
fragment one layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment 1"
android:layout_gravity="center"
android:gravity="center"
android:background="#FF5722"/>
</LinearLayout>
frament one java:
public class FirstFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
View view = inflater.inflate(R.layout.home, container,false);
if(container==null){
Log.d("First","Null");
return view;
}Log.d("First"," Not Null");
return null;
}
}
use this in switch
switch(menuItem.getItemId()) {
case R.id.nav_first_fragment:
getSupportFragmentManager().beginTransaction().replace(R.id.container, new FirstFragment()).commit();
break;
case R.id.nav_second_fragment:
getSupportFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();
break;
}
and make sure you give the correct IDs to the switch. And "container" is the ID for the layout of the activity_main.xml
just give the ID to main Layout like
android:id="#+id/container"
I'm having a hell of a time getting fragments to work. The basis of this is to lave a login screen (fragment) appear by default when LoginActivity is created. The fragment has an TextView that when clicked, is supposed to launch a new fragment (form for lost password). I keep getting a NullPointerException when calling forgottenPassword.setOnClickListener from LoginActivity.
The project crashes before I can tell if anything else works.
I'm sure there's some glaring newbie error in here somewhere...
onCreate method from LoginActivity.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (savedInstanceState == null) {
FragmentManager fragmentManager = getFragmentManager();
int fragmentTransaction = fragmentManager.beginTransaction()
.add(R.id.login_screen_fragment, new FragmentLogin())
.commit();
}
// Listen for FORGOTTEN PASSWORD click event, open ForgottenPassword Fragment //
final TextView forgottenPassword = (TextView) findViewById(R.id.button_lost_pass);
forgottenPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do what I need this to do...
}
});
}
layout_login.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/login_screen_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity"
/>
fragment_login:
<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="come.xxxx.xxxx.ForgottenPasswordFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/login_email"
android:id="#+id/login_forgot"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="#string/login_send_lost_pass"
android:id="#+id/button_lost_pass"
/>
</LinearLayout>
</FrameLayout>
fragment_lost_password.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.xxxx.xxx.FragmentLogin">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:orientation="vertical"
android:layout_gravity="center"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I forgot my password"
android:gravity="center"
android:layout_marginTop="32dp"
android:padding="8dp"
android:textSize="16sp"
android:id="#+id/login_forgot"
/>
</LinearLayout>
</ScrollView>
</FrameLayout>
FragmentLogin.java:
public class FragmentLogin extends Fragment {
public FragmentLogin() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_login, container, false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
final Activity activity = getActivity();
}
}
FragmentLostPassword.java
public class FragmentForgottenPassword extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_forgotten_password, container, false);
}
}
Error Trace:
05-13 12:49:37.222 15163-15163/com.xxxxx.xxxxx E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xxxxx.xxxxx, PID: 15163
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxxx.xxxxx/com.xxxxx.xxxxx.LoginActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.xxxxx.xxxxx.LoginActivity.onCreate(LoginActivity.java:51)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
05-13 12:50:28.592 15163-15173/com.xxxxx.xxxxx W/art: Suspending all threads took: 15.077ms
05-13 12:50:44.622 15163-15163/? I/Process: Sending signal. PID: 15163 SIG: 9
You have to find the View in your Fragment's layout.
Use the following in your FragmentLogin class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_login, container, false);
final TextView forgottenPassword = (TextView) view.findViewById(R.id.button_lost_pass);
// Set your onClickListener here
return view;
}
Actually, your fragment might be not accessible when you assign forgetpassword , you can use the following for layout_login.xml:
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:name="FragmentLogin"
tools:layout="#layout/fragment_login"
/>
Note you may have to define the right path to FragmentLogin.
This is the new way to work with fragment, that will load your Login fragment automatically without writing anything in onCreate.
Also, it's not a TextView but a Button
Finally, remove the Fragment Transaction code.
Another option, is to move your forgot password button login to FragmentLogin. Because basically you try to access Fragment related element from the activity. Everything should be in your fragment.
You can still access the fragment manager with getActivity().getFragmentManger(), to load the lost_password layout.
What is the activity_login.xml content. I guest wrong id of button button_lost_pass
Inside oncreate() method you called new Fragment but the fragment layout(layout_lost_password) does not contain the id(R.id.button_lost_pass)
Change :
final TextView forgottenPassword = (TextView) findViewById(R.id.button_lost_pass);
To
final Button forgottenPassword = (Button) findViewById(R.id.button_lost_pass);
I'm actually programming an Android app that uses Google Maps API.
The layout activity_main.xml looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment"
map:mapType="normal"
map:uiCompass="false"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="false"
map:uiZoomGestures="true" />
</LinearLayout>
And I load the map asynchronically in the fragment. When I try to inflate the activity_main view:
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup mainView = (ViewGroup) inflater.inflate(R.layout.activity_main, null);
The app crashes and returns an error:
01-15 19:25:16.045: E/AndroidRuntime(21115): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
How can i solve it? I need this ViewGroup to set a Power Button KeyListener to the app (similar to what I did in another app without fragment):
mainView.setOnKeyListener(new OnKeyListener()
{
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_POWER)
{
//STUFF
}
}
});
Thank you for your help :D
namespace must be declared in the first view
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/mapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment"
map:mapType="normal"
map:uiCompass="false"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="false"
map:uiZoomGestures="true" />
</LinearLayout>
Did you add this lines in your manifest file:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="YOUR_KEY" />
Take a look on this site
https://docs.google.com/document/pub?id=19nQzvKP-CVLd7_VrpwnHfl-AE9fjbJySowONZZtNHzw
I've almost solved the problem. I've created a custom SupportMapFragment class and I'm loading the fragment in a FrameLayout dynamically.
The activity_main.xml looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/mapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/mapPlaceholder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I can now inflate the activity_main through code:
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup mainView = (ViewGroup) inflater.inflate(R.layout.activity_main, null);
After this, I've set the listener (100% working):
mainView.setFocusableInTouchMode(true);
mainView.setOnKeyListener(new OnKeyListener()
{
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
//STUFF
}
});
And I've added the view like this:
final WindowManager myWindowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
myWindowManager.addView(mainView, viewParams);
I'm not using the setContentView anywhere in onCreate so here's the second problem. I need to load the GoogleMap in the FrameLayout through FragmentTransaction.
FragmentTransaction needs setContentView to work. This code:
FrameLayout mapPlaceholder = (FrameLayout) mainView.findViewById(R.id.mapPlaceholder);
if(mapPlaceholder != null) {
mapFragment = GoogleMapFragment.newInstance();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(mapPlaceholder.getId(), mapFragment, GoogleMapFragment.class.getName());
ft.commit();
}
Returns this error when launching the application:
01-16 18:22:20.263: E/AndroidRuntime(7755): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070018 (com.example.app:id/mapPlaceholder) for fragment GoogleMapFragment{b666a7d #0 id=0x7f070018 com.example.app.GoogleMapFragment}
Does anyone know how to use the FragmentTransaction (or add a Fragment) without setContentView?
I have three Fragments and they are arranged as shown below:
"Frag A and Frag C is not connected, but Frag B and C are. The each fragment contains 1 listview so every time I triggered an event it will go to the next fragment."
Fragment A ---> (Inside Frag A)Fragment B ---> (Inside Frag B)Fragment C
Fragment A(main.xml)
Fragment B(R.id.contentFragment)
Fragment C(R.id.contentFragment)
I can display Fragment A and Fragment B and is okay, but if I call Fragment C from BI got "No view found in contentFragment=0x7f040039".
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/white"
android:id="#+id/frameLayout"
>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"
>
</ListView>
<FrameLayout
android:id="#+id/contentFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
</FrameLayout>
</FrameLayout>
</FrameLayout>
FragmentA.java
Inside Fragment A to open Fragment B
Fragment fragment1 = new FragmentB();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.contentFragment, fragment1, fragMainGroups );
transaction.addToBackStack(fragMainGroups);
transaction.commit();
FragmentB.java
Inside Fragment B to open Fragment C
String fragGroups = "groups";
Fragment fragment1 = new FragmentC();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.contentFragment, fragment1, fragGroups );
transaction.addToBackStack(fragGroups);
transaction.commit();
FragmentC.java
Inside Fragment C
public class FragmentItems extends ListFragment{
public void onAttach(Activity activity) {
super.onAttach(activity);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void onCreate(Bundle e)
{
super.onCreate(e);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.load_items_activity, container, false);
return rootView;
}
}
Logcat
07-25 18:10:20.388: E/FragmentManager(24703): No view found for id 0x7f040039 (com.jinisys.restoplusordering:id/contentFragment) for fragment FragmentItems{4156f480 #0 id=0x7f040039 groups}
07-25 18:10:20.388: E/FragmentManager(24703): Activity state:
07-25 18:10:20.388: E/FragmentManager(24703): No view found for id 0x7f040039 (com.jinisys.restoplusordering:id/contentFragment) for fragment FragmentItems{4156f480 #0 id=0x7f040039 groups}
07-25 18:10:20.388: E/FragmentManager(24703): Activity state:
07-25 18:10:20.718: E/AndroidRuntime(24703): FATAL EXCEPTION: main
07-25 18:10:20.718: E/AndroidRuntime(24703): java.lang.IllegalArgumentException: No view found for id 0x7f040039 (com.jinisys.restoplusordering:id/contentFragment) for fragment FragmentItems{4156f480 #0 id=0x7f040039 groups}
07-25 18:10:20.718: E/AndroidRuntime(24703): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
07-25 18:10:20.718: E/AndroidRuntime(24703): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
07-25 18:10:20.718: E/AndroidRuntime(24703): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
07-25 18:10:20.718: E/AndroidRuntime(24703): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
07-25 18:10:20.718: E/AndroidRuntime(24703): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
07-25 18:10:20.718: E/AndroidRuntime(24703): at android.os.Handler.handleCallback(Handler.java:615)
As your error states you are looking for a view with id contentFragmentTtems inside Fragment B, main view for which is contentFragment and not the whole main.xml. So if you want to add new fragment you should do it also from Fragment A.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/white"
android:id="#+id/frameLayout"
>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"
>
</ListView>
<FrameLayout
android:id="#+id/contentFragmentb"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:id="#+id/contentFragmentc"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
</FrameLayout>
</FrameLayout>
</FrameLayout>
This should work.