0

I decided to use fragments as an alternative to activities, so I cut up my activity_main.xml into 2 different XML files: activity_main.xml and fragment_main.xml. The problem is that the relativeLayout previously in activity_main that I was referencing in java is no longer working after I moved it to the other XML file. It looks like you need to set the content view of whatever XML file you're using in order to findViewByID, but filling in my graph with barchart data might require both; the fragment_main.xml needing to be set as my content view (it's the blank that I'm filling in with other fragments) and the activity_main needing to be set to display it as a part of my main screen. The fSetGraph(); is using this graph: https://github.com/PhilJay/MPAndroidChart

Out of curiousity: do layout inflaters come into play anywhere in here?

MainActivity.java

        public class MainActivity extends AppCompatActivity {

            private DrawerLayout mDrawer;
            private Toolbar toolbar;
            private RecyclerView recyclerView;
            private NavigationView nvDrawer;
            FloatingActionButton fab;
            FragmentManager manager = getSupportFragmentManager();

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                setContentView(R.layout.fragment_main);
                fSetGraph();
                fsetFAB();

        //        setContentView(R.layout.activity_main);
        //        fSetToolBar();
        //        fSetDrawer();
        //        fSetDrawerContent();
        //        fsetInitialFragment();


            }


    private void fSetGraph() {
.
.  //Lots of code here about setting the graph. Not important.
.


    RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayoutForChart);
    rl.addView(MainActivity.barChartGlobal,
                    new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT));

    }

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"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/linearLayoutMainActivity"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">


            <!-- The ActionBar -->
            <include
                layout="@layout/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>





            <RelativeLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/relativeLayoutActivity"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:background="#FFFFFF">




                <!--Fragments placed here-->





            </RelativeLayout>

        </LinearLayout>

        <!-- The navigation drawer -->
        <android.support.design.widget.NavigationView
            android:id="@+id/nvView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@android:color/white"
            app:menu="@menu/drawer_view"
            app:headerLayout="@layout/drawer_header">

            <!--<include-->
            <!--layout="@layout/drawer_header"-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="160dp"/>-->

        </android.support.design.widget.NavigationView>





    </android.support.v4.widget.DrawerLayout>

fragment_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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">



    <!-- Here on down is the fragment I'm using in activity_main.xml-->


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="false"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:id="@+id/relativeLayoutForChart"
        android:layout_above="@+id/linearLayoutForCenterReference"
        android:layout_below="@+id/linearLayoutHeader">


        <com.github.mikephil.charting.charts.BarChart
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/chart"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_gravity="center"
            android:layout_alignParentBottom="true"
            android:layout_alignParentTop="false" />




    </RelativeLayout>


    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/linearLayoutForCenterReference">
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayoutLabels"
        android:gravity="center_vertical|center_horizontal"
        android:layout_alignTop="@+id/linearLayoutForCenterReference"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="false"
        android:layout_centerHorizontal="true"
        android:layout_toRightOf="@+id/relativeLayoutSchedule"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="tv1"
            android:id="@+id/textView1"
            android:textSize="15dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="tv2"
            android:id="@+id/textView2"
            android:textSize="15dp"
            android:layout_marginLeft="52dp"
            android:layout_marginRight="52dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="tv3"
            android:id="@+id/textView3"
            android:textSize="15dp" />
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:id="@+id/linearLayoutHeader"
        android:layout_alignParentEnd="true"
        android:layout_alignParentStart="true"
        android:gravity="center_horizontal">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="One"
                android:id="@+id/textViewOne"
                android:layout_alignParentTop="true"
                android:layout_toLeftOf="@+id/textViewState"
                android:layout_toStartOf="@+id/textViewState" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="Two"
                android:id="@+id/textViewTwo"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true"
                android:layout_marginLeft="50dp"
                android:layout_marginRight="40dp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="Three"
                android:id="@+id/textViewThree"
                android:layout_alignParentTop="true"
                android:layout_toRightOf="@+id/textViewState"
                android:layout_toEndOf="@+id/textViewState" />
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/linearLayoutLabels"
        android:layout_centerHorizontal="true"
        android:id="@+id/linearLayoutActivityFeed"
        android:gravity="center_vertical|center_horizontal"
        android:paddingTop="0dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="3dp">

        <ImageView
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:id="@+id/imageView2"
            android:src="@drawable/ic_assignment_black_24dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Activity Feed"
            android:id="@+id/textViewActivityFeed"
            android:layout_marginBottom="1dp" />
    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/linearLayoutActivityFeed"
        android:layout_centerHorizontal="true"
        android:id="@+id/relativeLayoutForTabs">









        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:gravity="right">



            <android.support.design.widget.TabLayout
                android:id="@+id/sliding_tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>



            <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.v4.view.ViewPager>





        </android.support.design.widget.AppBarLayout>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_add_black_24dp"
            android:layout_marginBottom="20dp"
            android:layout_marginRight="20dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/drawer_recyclerView"
            android:layout_width="match_parent"
            android:layout_gravity="start"
            android:layout_height="match_parent"
            android:background="#FFFFFF">

        </android.support.v7.widget.RecyclerView>


    </RelativeLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/linearLayoutForCenterReference"
        android:layout_above="@+id/linearLayoutActivityFeed"
        android:layout_alignParentStart="false"
        android:layout_alignParentEnd="false"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="false"
        android:id="@+id/relativeLayoutSchedule"
        android:layout_alignParentTop="false"
        android:gravity="center_vertical"
        android:layout_alignTop="@+id/linearLayoutLabels"
        android:layout_marginLeft="15dp">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:id="@+id/imageViewSchedule"
            android:src="@drawable/ic_event_black_24dp"
            android:contentDescription="Event Icon" />
    </RelativeLayout>



</RelativeLayout>

Trying to run that ending part of fSetGraph() with the contentView set to activity_main instead of fragment_main (which the graph is in) gives me the error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{...MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.RelativeLayout.addView(android.view.View, android.view.ViewGroup$LayoutParams)' on a null object reference

Nav Drawer code

    switch (menuItem.getItemId()) {
            case R.id.navigation_item_log_in:

                DialogPopupSignInFragment alertDialogSignInCustom = new DialogPopupSignInFragment();
                alertDialogSignInCustom.show(manager, "DialogSignIn");

                break;

            case R.id.navigation_item_home:


                FragmentMain fragmentMain = new FragmentMain();
                FragmentTransaction transaction = manager.beginTransaction();
                transaction.replace(R.id.relativeLayoutActivity, fragmentMain, "Home");
                transaction.commit();

                setTitle("App Home");


                break;

            case R.id.my_stats:

                FragmentMyStats fragmentMyStats = new FragmentMyStats();
                FragmentTransaction transactionMyStats = manager.beginTransaction();
                transactionMyStats.replace(R.id.relativeLayoutActivity, fragmentMyStats , "MyStats");
                transactionMyStats.commit();

                setTitle("My Stats");

                break;

            case R.id.navigation_item_winners:

                FragmentWinners fragmentWinners = new FragmentWinners();
                FragmentTransaction transactionWinners = manager.beginTransaction();
                transactionWinners.replace(R.id.relativeLayoutActivity, fragmentWinners, "Winners");
                transactionWinners.commit();

                setTitle("Winners");

                break;

            case R.id.navigation_item_settings:

                FragmentSettings fragmentSettings = new FragmentSettings();
                FragmentTransaction transactionSettings = manager.beginTransaction();
                transactionSettings.replace(R.id.relativeLayoutActivity, fragmentSettings, "Settings");
                transactionSettings.commit();

                setTitle("Settings");

                break;

            case R.id.navigation_item_about:

                FragmentAbout fragmentAbout = new FragmentAbout();
                FragmentTransaction transactionAbout = manager.beginTransaction();
                transactionAbout.replace(R.id.relativeLayoutActivity, fragmentAbout, "About");
                transactionAbout.commit();

                setTitle("About");

                break;

        }

Setting up my Drawer in MainActivity

private void fSetDrawer() {
        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.app_name, R.string.app_name);
        mDrawer.setDrawerListener(drawerToggle);
        drawerToggle.syncState();
    }

Navigation Drawer XML from activity_main

<android.support.design.widget.NavigationView
            android:id="@+id/nvView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@android:color/white"
            app:menu="@menu/drawer_view"
            app:headerLayout="@layout/drawer_header">

            <!--<include-->
            <!--layout="@layout/drawer_header"-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="160dp"/>-->

        </android.support.design.widget.NavigationView>

Navigation Drawer Menu

<group
        android:checkableBehavior="single">

        <item
            android:id="@+id/navigation_item_log_in"
            android:icon="@drawable/ic_person_black_24dp"
            android:title="Log In">
        </item>

        <item
            android:id="@+id/navigation_item_home"
            android:icon="@drawable/ic_home_black_24dp"
            android:title="Home">
        </item>

        <item
            android:id="@+id/my_stats"
            android:icon="@drawable/ic_developer_board_black_24dp"
            android:title="My Stats">
        </item>

        <item
            android:id="@+id/navigation_item_winners"
            android:icon="@drawable/ic_wb_iridescent_black_24dp"
            android:title="Winners">
        </item>

        <item
            android:id="@+id/navigation_item_settings"
            android:icon="@drawable/ic_settings_black_24dp"
            android:title="Settings">
        </item>

        <item
            android:id="@+id/navigation_item_about"
            android:icon="@drawable/ic_local_library_black_24dp"
            android:title="About">
        </item>

        <!--Recycler View-->





    </group>
FiringBlanks
  • 1,998
  • 4
  • 32
  • 48
  • 2
    You need to move that part of code to your fragment class. For more information, you can read http://developer.android.com/guide/components/fragments.html – Nishant Sep 01 '15 at 08:16
  • Is that because the fragment class normally inflates it? – FiringBlanks Sep 01 '15 at 10:26

1 Answers1

1

Yes its to do with layout inflaters. What is happening is when you use findViewById, the activity ONLY checks the layout in its setContectView which in your case is activity_main. Because of this the activity is unable to find r1. The solution to this is the inflate r1 in a fragment and then reference it by your main activity.

import android.support.v4.app.Fragment; //Edit : make sure its this

public class MapFragment extends Fragment{ 

View v //EDIT

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        v=inflater.inflate(R.layout.fragment_main, container, false);

 RelativeLayout rl = (RelativeLayout) v.findViewById(R.id.relativeLayoutForChart); //EDIT
rl.addView(barchart,
                new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
        return v;

}

Make a new class with this in it. Then in your main activity type in this code

FragmentTransaction ft = ((FragmentActivity)mContext).getSupportFragmentManager().beginTransaction();
MapFragment mapFragment=new MapFragment();
ft.replace(R.id.fragment_map, placeOrderFragment).addToBackStack(null).commit();

In your main_activity xml, add a with id of map_fragment.

Basically the flow will be your map will be put into the fragment xml, this will then be inflated by the fragment class, this will then be used by the main activity.

EDIT : Tweaked code. Do have a look. When a layout is being inflated, to find view groups within that layout, it has to passed as well along with findViewById so a small change is needed. Also when you define the fragment, make sure you import the v4. one so its backward compatible.

Varun Agarwal
  • 1,587
  • 14
  • 29
  • My FragmentMain.java class that inflates my layout says it 'can't resolve method findViewById', so I appended getView() to it and it's giving me a NullPointerException error. – FiringBlanks Sep 01 '15 at 22:26
  • 1
    sorry my bad. To use findViewById, a context or a view is needed from an activity. So in the case of a fragment you have to change findViewwById to v.findViewById and it will work. – Varun Agarwal Sep 02 '15 at 05:25
  • Wow that worked. It loads up fine as my first fragment. But I start clicking around on my navigation drawer to some other fragment screens and come back to this (my 'Home' fragment) and I'm getting the error: `java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.`. I posted the code I'm running in the nav drawer to bring me to my Home fragment above, on the very bottom of the post. – FiringBlanks Sep 02 '15 at 06:30
  • think you should remove "Home" from this line and leave it as transaction.replace(R.id.relativeLayoutActivity, fragmentMain); – Varun Agarwal Sep 02 '15 at 08:03
  • "Home" is just a tag to refer back to this transaction with later. It shouldn't affect execution. I just tried it without the tag and it works the same. I'm looking here also http://stackoverflow.com/questions/6526874/call-removeview-on-the-childs-parent-first but I can't decipher any meaningful help from it. – FiringBlanks Sep 02 '15 at 09:48
  • send me the code where you handle/ inflate the navigation drawer. I think you are implementing it wrong. Can you +1 my answer :D – Varun Agarwal Sep 02 '15 at 09:49
  • How do I send messages? I've included the navigation drawer code at the bottom of the post. – FiringBlanks Sep 02 '15 at 10:04
  • Thanks, I'll email you if you need more code. The nav code is definitely up now. – FiringBlanks Sep 02 '15 at 10:12