0

I'm attempting to use fragments to give a different display depending on whether the app is being run on a phone or a tablet - as fragments are supposed to be used.

I have the following XML for my layouts:

layout/main.xml:

<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"  >

    <RelativeLayout
        android:id="@+id/list_fragment_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

layout-large/main.xml:

<LinearLayout 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" 
    android:orientation="horizontal"
    android:baselineAligned="false" >

    <RelativeLayout
        android:id="@+id/list_fragment_view"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2" />

    <RelativeLayout
        android:id="@+id/sales_agreement_fragment_view"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="7" />

</LinearLayout>

I havetried using FrameLayouts instead of the RelativeLayouts in the second example - it didn't seem to make any difference.

My Activity onCreate() code is as follows:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        FragmentManager manager = getFragmentManager();
        View salesAgreementLayout = findViewById(R.id.sales_agreement_fragment_view);
        Fragment formsListFragment = new KingdomSpasFormsListFragment();

        FragmentTransaction fragmentTransaction = manager.beginTransaction();
        fragmentTransaction.add(R.id.list_fragment_view,formsListFragment);
        if (salesAgreementLayout != null) {
            Fragment salesAgreementFragment = new SalesAgreementFragment();
            fragmentTransaction.add(R.id.sales_agreement_fragment_view, salesAgreementFragment);
        }

        fragmentTransaction.commit();

    }

However, running this (whether on a phone or a tablet results in the following error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kingdomspas.android.kingdomspasforms/com.kingdomspas.android.kingdomspasforms.activities.KingdomSpasFormsActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.kingdomspas.android.kingdomspasforms:id/list_fragment_view) for fragment KingdomSpasFormsListFragment{527f671c #0 id=0x7f070000}

I've Googled this extensively as it seems to be a common problem. The main solution, however, seem to be that the original layout specified in setContentView() doesn't contain the Views later referenced in the add() methods. However, this is definitely not the problem in my case (unless I'm being ridiculously blind - I've checked and re-checked).

In fairness, I'm not actually certain that this is the best UI design for my app - I'm wondering about tabs perhaps - but, either way, I'd really like to understand what the problem is here and what I'm doing wrong - else I'm likely doomed to repeat it in the future.

Paul Hunnisett
  • 898
  • 1
  • 17
  • 36

1 Answers1

0

Here is a great tutorial on multipane fragments for android. http://www.vogella.com/tutorials/AndroidFragments/article.html

With regards to your problem if you add static fragments in your layout it will solve your problem. If you have a definite need for dynamic fragments I would suggest doing a check for what sort of device that application is running on before you find the view i.e.

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        FragmentManager manager = getFragmentManager();
        View salesAgreementLayout = findViewById(R.id.sales_agreement_fragment_view);
        Fragment formsListFragment = new KingdomSpasFormsListFragment();

        FragmentTransaction fragmentTransaction = manager.beginTransaction();
        fragmentTransaction.add(R.id.list_fragment_view,formsListFragment);
        if (isTablet()){
            Fragment salesAgreementFragment = new SalesAgreementFragment();
            fragmentTransaction.add(R.id.sales_agreement_fragment_view, salesAgreementFragment);
        }

        fragmentTransaction.commit();


    }

    public boolean isTablet() {
        return (getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
    }

the is tablet method was adapted from How to detect device is Android phone or Android tablet?

Community
  • 1
  • 1
Justin Slade
  • 500
  • 2
  • 7
  • I am checking for the type of device (or, at least, I thought I was) by checking to see if salesAgreementLayout is null. Since it only exists in the layout-large file, it should also only exist as an Object on a tablet or large screen device. – Paul Hunnisett May 29 '14 at 13:46