3

I am attempting to complete the Android HelloWorld App using Eclipse and the ADT. However, the app always crashes when I implement the second activity and press the "Send" button. Here are the relevant files (with imports truncated):

fragment_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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.myfirstapp.MainActivity$PlaceholderFragment" >

<EditText android:id="@+id/edit_message"
    android:layout_weight="1"        
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:hint="@string/edit_message" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_send"
    android:onClick="sendMessage" />  

fragment_display_message.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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.myfirstapp.DisplayMessageActivity$PlaceholderFragment" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

activity_display_message.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.myfirstapp.DisplayMessageActivity"
tools:ignore="MergeRootFrame" />

MainActivity.java

public class MainActivity extends ActionBarActivity {

public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";

public void sendMessage(View view) {
    Intent intent = new Intent(this, DisplayMessageActivity.class);
    EditText editText = (EditText) findViewById(R.id.edit_message);
    String message = editText.getText().toString();
    intent.putExtra(EXTRA_MESSAGE, message);
    startActivity(intent);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

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

}

DisplayMessageActivity.java

public class DisplayMessageActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {    
    super.onCreate(savedInstanceState);     
    Intent intent = getIntent();
    String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
    TextView textView = new TextView(this);
    textView.setTextSize(40);
    textView.setText(message);
    setContentView(textView);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.display_message, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_display_message,
                container, false);
        return rootView;
    }
}

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstapp"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="19" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.myfirstapp.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name="com.example.myfirstapp.DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>
</application>

And finally, the LogCat file:

03-20 22:25:46.427: E/AndroidRuntime(32293): FATAL EXCEPTION: main
03-20 22:25:46.427: E/AndroidRuntime(32293): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myfirstapp/com.example.myfirstapp.DisplayMessageActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f05003c (com.example.myfirstapp:id/container) for fragment PlaceholderFragment{4137cd30 #0 id=0x7f05003c}
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1159)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.os.Looper.loop(Looper.java:137)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.ActivityThread.main(ActivityThread.java:4507)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at java.lang.reflect.Method.invokeNative(Native Method)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at java.lang.reflect.Method.invoke(Method.java:511)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:978)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at dalvik.system.NativeStart.main(Native Method)
03-20 22:25:46.427: E/AndroidRuntime(32293): Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f05003c (com.example.myfirstapp:id/container) for fragment PlaceholderFragment{4137cd30 #0 id=0x7f05003c}
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1136)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.Activity.performStart(Activity.java:4479)
03-20 22:25:46.427: E/AndroidRuntime(32293):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1941)
03-20 22:25:46.427: E/AndroidRuntime(32293):    ... 11 more

I know the issue lies with the conditional in onCreate in DisplayMessageActivity.java, but I have no idea how to fix it. I'd be grateful for any help in understanding why this simple app - essentially copy-pasted from the Android site - will not run.

Ashley Medway
  • 7,151
  • 7
  • 49
  • 71
Nick Broderick
  • 289
  • 3
  • 7
  • can you paste the layout file of DisplayMessageActivity? – k3v1n4ud3 Mar 21 '14 at 02:02
  • From the logcat this "java.lang.IllegalArgumentException: No view found for id 0x7f05003c " looks like something to look into – Chris Mar 21 '14 at 02:04
  • I'll have it up in a moment. – Nick Broderick Mar 21 '14 at 02:06
  • @Chris I don't see how this is relevant: the last line in onCreate in my DisplayMessageActivity sets the layout with setContentView(textView) using a textView instantiated in the method. If I'm missing something please help me see it. – Nick Broderick Mar 21 '14 at 02:24

3 Answers3

5

I had similar problem. When I rechecked the tutorial from which you are also learning i.e. developer.android, I found that in the onCreate method of DisplayMessageActivity class the following codes of lines are causing disruptions,(I have commented it)

if (savedInstanceState == null) {
       getSupportFragmentManager().beginTransaction()
               .add(R.id.container, PlaceholderFragment.newInstance(message)).commit();
   }

Please delete these lines. If you carefully observe the tutorial there they present the code of onCreate at last to cross check, there these line are missing. :)

JDP
  • 385
  • 3
  • 7
4

In displayMessageActivity, you set the content view to a textView, but it should be activity_display_message.xml instead because that's where your container is defined. So that's why the fragment manager can't find any container to add the fragment. You can pass the text to the fragment so that it will handle setting the text to the textView.

Try something like:

public class DisplayMessageActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent intent = getIntent();
    String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
    setContentView(R.layout.activity_display_message);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, PlaceholderFragment.newInstance(message)).commit();
    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.display_message, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    private static final String ARG_MESSAGE = "ARG_MESSAGE";

    public static PlaceholderFragment newInstance(String message) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putString(ARG_MESSAGE, message);
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_display_message,
                container, false);
        final String message = getArguments().getString(ARG_MESSAGE);
        final TextView tv = (TextView) rootView.findViewById( id of your textview );
        tv.setText(message);
        return rootView;
    }
}
k3v1n4ud3
  • 2,904
  • 1
  • 15
  • 19
  • Thank you for the help. A noob question though: what textView are you talking about? Do I define it using a new XML file? – Nick Broderick Mar 21 '14 at 03:12
  • In your fragment_display_message.xml you have a textView with the text hello world, I figured you wanted to change the text of that one. – k3v1n4ud3 Mar 21 '14 at 04:14
  • You need to set an id to the TextView in fragment_display_message.xml. See Building a Simple User Interface in the tutorial for an explanation on how you do that. – Fredrik Apr 09 '14 at 20:43
  • Why do we need this `Bundle` and `fragment.setArguments` thing, why can't we just give our `PlaceholderFragment` constructor a parameter for this? – Bergi Jul 20 '15 at 21:29
  • You can try using a constructor with parameter, you should see something like "Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead". The reason for this is that when the system needs to recreate your fragment, it will use the default constructor so sticking to one default constructor helps you make sure you assign your variables in another place, to avoid future problems. – k3v1n4ud3 Jul 21 '15 at 03:28
2

According to this line:

No view found for id 0x7f05003c (com.example.myfirstapp:id/container) for fragment PlaceholderFragment{4137cd30 #0 id=0x7f05003c} 

You never declare your R.id.container item. And it's right - you never do declare it in your XML layout. I'm not exactly sure what you're trying to do with that, but you should add that to your XML layout, or just remove it (it doesn't really look like you're using it).

It doesn't really look like the fragment you declare is needed. As it's just a simple activity, a fragment shouldn't really be needed.

hichris123
  • 10,145
  • 15
  • 56
  • 70
  • I figured that the fragmentation code was ultimately unnecessary, but R.id.container IS defined in activity_display_message.xml (I did not have it posted when you provided your answer). – Nick Broderick Mar 21 '14 at 02:13