i am very new to Android Developing, have been developing mainly for ios for several years now but having problems in my first android app.
I am developing an app where at the beginning you have log in, so i created the UI and the login button and so far that works great, the app is able to connect to the database a download the necessary information for it to work via xml.
The downloaded Xml gives the items in the navigation drawer their names,
Basically all of the navigation drawer items should lead you to the same fragment, the content changes when loading the contents of the downloaded xml to it, but the window remains the same.
So in order to do this i created the navigation drawer items programmatically, added the ui for the fragment in a new xml.
When running the app everything works great, once you are logged in you are able to open the NavigationDrawer by swiping right, the right Items and names appear, but when clicking an item... nothing happens.
I used LOGE to know if the code was working and witch menu item was trying to open and it does return always the right menu item etc.
If there is a code in the fragment it executes the code and returns what its expected, but its simply not visible.
Here is my onNavigationItemSelected in MainActivity.
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
String title = item.getTitle().toString();
int order = (int) getMenuItemTag(item);
if (title != "Modos Personales" && title != "Home") {
Log.e("onNavigationItem: ", Integer.toString(order));
Fragment fragment = null;
Class fragmentClass;
fragmentClass = MainFragment.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.flContent, fragment);
fragmentTransaction.commit();
} catch (Exception e) {
e.printStackTrace();
}
//FragmentManager fragmentManager = getFragmentManager();
//android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
//fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
}
Here is the XML of my main activity "activity_main.xml"
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<FrameLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
Here is app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context="com.paranoidinteractive.heimer.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
android:foreground="#mipmap/logo_menu"
android:foregroundGravity="center">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="#style/Base.Theme.AppCompat.Light"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
Here is the XML of my Fragment "room_view.xml"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/room_view"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorScreen"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView"
android:layout_gravity="center_vertical" />
</LinearLayout>
and here is my fragmet "MainFragment.java"
public class MainFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
int number = 0;
if (inflater != null){
Log.e("INFLATER NO NULL: ", Integer.toString(number));
} else {
Log.e("INFLATER NULL: ", Integer.toString(number));
}
if (container != null){
Log.e("CONTAINTER NO NULL: ", Integer.toString(number));
} else {
Log.e("CONTAINER NULL: ", Integer.toString(number));
}
return inflater.inflate(R.layout.room_view, container, false);
}
}
And if you view the LOGCAT it allways returns:
01-26 16:27:36.771 9259-9259/com.paranoidinteractive.heimer E/INFLATER NO NULL:: 0
01-26 16:27:36.771 9259-9259/com.paranoidinteractive.heimer E/CONTAINER NO NULL:: 0
So i know its working and getting there but its simply not showing it.
I've followed all the tutorials available and read tons of questions and answers here but none of the answers have helped me so far so i Decided to post this question.
Thank you in advance for your help, hope you can assist me with this.
Sorry for the log post!
Related
This is what i'm trying to achieve
I want settings menu click will appear side nav drawer
HomeActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mMainFrame = (FrameLayout) findViewById(R.id.main_frame);
mMainNav = (BottomNavigationView) findViewById(R.id.main_nav);
homeFragment = new HomeFragment();
analyticsFragment = new AnalyticsFragment();
paymentFragment = new PaymentFragment();
settingsFragment = new SettingsFragment();
drawerLayout = findViewById(R.id.drawerlayout);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_frame,new HomeFragment()).commit();
mMainNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.navigation_home:
setFragment(homeFragment);
return true;
case R.id.navigation_analytics:
setFragment(analyticsFragment);
return true;
case R.id.navigation_payment:
setFragment(paymentFragment);
return true;
case R.id.navigation_settings:
drawerLayout.openDrawer(GravityCompat.END);
return true;
default:
return false;
}
}
});
BottomNavigationView navView = findViewById(R.id.main_nav);
navView.setItemIconTintList(null);
And this is the error i get
Unable to start activity ComponentInfo{com.example.ewallet/com.example.ewallet.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.app.Activity.findViewById(int)' on a null object reference
EDIT : I tried to paste some of my code here but StackOverflow error too many code to post
You didn't bind your object correctly and caused a NullPointerException.
Please paste your code and we can help you.
I saw a weird part, but maybe this error will still appear, you may need to paste your layout.xml
mMainNav = (BottomNavigationView) findViewById(R.id.main_nav);
BottomNavigationView navView = findViewById(R.id.main_nav);
navView.setItemIconTintList(null);
Should be modify to
mMainNav.setItemIconTintList(null);
You can check if it is null with
getActivity().findViewById(R.id.XXX)
UPDATE
drawerLayout = (DrawerLayout)getView().findViewById(R.id.drawerlayout);
case R.id.navigation_settings:
drawerLayout.openDrawer(drawerLayout);
return true;
Took me 4 days to figure this out. Turned out you need to have drawerlayout in your activity layout. My problem was drawerlayout from different xml that's why returned null. Thx for those who tried for helping me
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:fitsSystemWindows="true"
tools:openDrawer="end">
<include
layout="#layout/app_bar_settings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_settings"
app:menu="#menu/activity_settings_drawer" />
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
tools:context=".HomeActivity">
<FrameLayout
android:id="#+id/main_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="56dp">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/main_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:labelVisibilityMode="labeled"
app:itemTextColor="#color/colorPrimaryDark"
app:menu="#menu/bottom_nav_menu" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.DrawerLayout>
I have a fragment that I would like to display on top of an activity. This is the code that I'm trying right now...
MainActivity.class
FragmentManager fragmentManager = getSupportFragmentManager();
DirectionsFragment directionsFragment = new DirectionsFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.add(R.id.directions_fragment_framelayout, directionsFragment);
fragmentTransaction.commit();
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
<!-- irrelevant parameters -->
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/directions_fragment_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<com.mapbox.mapboxsdk.maps.MapView>
<!-- A BUNCH OF CHILDREN -->
</com.mapbox.mapboxsdk.maps.MapView>
</RelativeLayout>
DirectionsFragment.class
public class DirectionsFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment_directions, container, false);
return viewGroup;
}
}
fragment_directions.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
<!-- irrelevant params -->
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/directions_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!-- irrelevant params -->
/>
</android.support.constraint.ConstraintLayout>
The activity itself runs fine; when I trigger the fragment to show, it runs through the FragmentTransaction and fragment view inflation fine (confirmed using logs and breakpoints). Since the fragment is being added to a FrameLayout, why isn't the fragment showing up? Thanks in advance!
I think it will be helpfull
Try to swap your FrameLayout and MapView in activity_main.xml
Your code is working fine but its behind the map view thats why its not showing.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
<!-- irrelevant parameters -->
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.mapbox.mapboxsdk.maps.MapView>
<!-- A BUNCH OF CHILDREN -->
</com.mapbox.mapboxsdk.maps.MapView>
<FrameLayout
android:id="#+id/directions_fragment_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
Add background color in your fragment layout because fragment loaded but transparent layout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:background="#android:color/white"
android:layout_height="match_parent">
<ListView
android:id="#+id/directions_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!-- irrelevant params -->
/>
</android.support.constraint.ConstraintLayout>
so I know there are a few topics around here that ask about this but none seemed to be the cause of my issue. I have an ActionBarActivity that is going to be switching between a few different fragments, but I'm having a problem getting one of the fragments to show up. The activity does show a fragment when it is first loaded and does that fine. Here is the code that is setting up the initial fragment with the method to switch between fragments that I'm using.
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
final ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("");
if (savedInstanceState == null) navigateTo(START_SCREEN);
}
public void navigateTo(int sectionNumber, Serializable objectParam) {
Fragment fragment = null;
switch (sectionNumber) {
case START_SCREEN:
fragment = createStartScreenFragment(); //returns an instance of the class for this fragment
break;
case SCREEN_TWO:
fragment = createSecondScreenFragment(); //returns an instance of the class for this fragment
break;
}
if (fragment == null) return;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction trans = fm.beginTransaction();
trans.add(R.id.activity_container, fragment, fragment.getTag());
trans.commit();
trans.show(fragment);
}
activity_containers.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:id="#+id/activity_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
The first fragment that loads successfuly
<GridLayout
android:id="#+id/fragment_start_screen"
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.android.Activity">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
/>
...
</GridLayout>
And here is the fragment xml that isn't showing up
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
And here is the misbehaving fragments relevant code:
public class SecondFragment extends Fragment {
public final static int SECTION_NUMBER = 1;
private String mTag = "TAG";
private ParentActivity parentActivity;
public SecondFragment() {
}
public static fragment newInstance() {
SecondFragment fragment = new SecondFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(final Activity activity) {
super.onAttach(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
parentActivity = (ParentActivity) getActivity();
View rootView = inflater.inflate(R.layout.fragment_second_fragment, container, false);
ListView list = (ListView) rootView.findViewById(R.id.list);
return super.onCreateView(inflater, container, savedInstanceState);
}
}
The biggest problem I'm having here is that there is no error message shown. The text view in the first fragment is supposed to trigger the second fragment to show up on the screen. This used to work when I had that fragment as a DialogFragment and just called .show() on an instance of it. I need it to be a regular fragment now and it doesn't show up. There's no error message that I can see, though debugging it does show it running through all of my code successfully and it looks like its properly inflating the view.
So what could I be missing here that is preventing the fragment from displaying?
Your layout
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
Should be within a ViewGroup
<?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="vertical">
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
</LinearLayout>
And you should return rootView in onCreateView().
Also, you might need to use replace method of Fragment Manager to replace one fragment with another, instead of add.
I have made a tab container with TabHost, the layout xml file is like below:
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="60dip" >
<fragment
android:id="#+id/tab1"
android:name="com.test.Tab1Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment
android:id="#+id/tab5"
android:name="com.test.Tab5Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</TabHost>
In MainActivity, I init and add tab into activity in onCreate callback like this,
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator(mRes.getString(R.string.tab1)).setContent(R.id.tab1));
tabHost.addTab(tabHost.newTabSpec("tab5").setIndicator(mRes.getString(R.string.tab5)).setContent(R.id.tab5));
On the tab changed, I want to find the current fragment, and do some init while current fragment is showing.
private OnTabChangeListener tabChangedListener = new OnTabChangeListener() {
public void onTabChanged(String tabid) {
Log.d(TAG, "tab changed " + tabid);
currentTab = tabid;
TabChangeCallback currentFragment = (TabChangeCallback) getFragmentManager().findFragmentByTag(currentTab);
if(currentFragment != null) {
currentFragment.onTabChanged(currentTabIndex);
} else {
Log.d(TAG, "get fragment null ");
}
}
};
Question is why getFragmentManager().findFragmentByTag(currentTab) is return null, and I couldn't call the fragment init code. thanks for your help.
I think if you are dealing with only fragment in the Tabhost then you better use FragmentTabHost. It will be more optimized and easy.
Example
And getting child fragment by Tag - link
This issue is because the fragemnt has not created at the time OnTabChnaged gets called.
Please check my answer here
I am trying to make a ListView with TextViews, I want each textview to be able to be clicked and based on it's position a Fragment is pulled up. However, the itemOnClickListener seems to not even be called.
mDrawerList = (ListView) findViewById(R.id.devices_drawer);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, drawerInfo));
mDrawerList.setItemsCanFocus(false);
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
final int pos, long id) {
Log.d(TAG, "CLICKED " + pos);
selectDevice(pos);
}
});
here's the xml for the list item:
<?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="vertical" >
<TextView
android:id="#+id/deviceText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
List view xml file:
<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" >
<ListView
android:id="#+id/devices_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.DrawerLayout>
It's your whole xml drawer (I presume you try to do a navigation drawer) ? If you have a parent layout check the android:descendantFocusability="blocksDescendants" otherwise you have to wrap your textview in a layout (LinearLayout is sufficient if you don't have a complex UI for the item).
The new OnItemClickListener is an AdapterView.OnItemClickListerner?
(An excellent how-to http://www.vogella.com/articles/AndroidActionBar/article.html#actionbar_navigation_drawer )
Is there a reason you are using mDrawerList.setItemsCanFocus(false);? You don't have any focusable items in your item layout, so it's safe to remove that call. Should work ok after that.
Also check if you are using Button in list row item, it'll over-ride you list item click event
For list items inside your list.. you have to set the attributes below
android:focusable="false"
android:focusableInTouchMode="false"