2

In my actvity I want to display some textviews at the top and then inflate a listview below it. I've attempted various methods without success, such as addview() but cannot get it to work. My inflated view becomes the main layout.

Any help would be much appreciated. LogCat Errors based on Ted Hopp solution

10-20 02:38:38.322: D/AndroidRuntime(1253): Shutting down VM 10-20 02:38:38.322: W/dalvikvm(1253): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 10-20 02:38:38.322: E/AndroidRuntime(1253): Uncaught handler: thread main exiting due to uncaught exception 10-20 02:38:38.342: E/AndroidRuntime(1253): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mycoursetimetable/com.example.mycoursetimetable.MyCourses}: java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called. 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.os.Handler.dispatchMessage(Handler.java:99) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.os.Looper.loop(Looper.java:123) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.ActivityThread.main(ActivityThread.java:4363) 10-20 02:38:38.342: E/AndroidRuntime(1253): at java.lang.reflect.Method.invokeNative(Native Method) 10-20 02:38:38.342: E/AndroidRuntime(1253): at java.lang.reflect.Method.invoke(Method.java:521) 10-20 02:38:38.342: E/AndroidRuntime(1253): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 10-20 02:38:38.342: E/AndroidRuntime(1253): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 10-20 02:38:38.342: E/AndroidRuntime(1253): at dalvik.system.NativeStart.main(Native Method) 10-20 02:38:38.342: E/AndroidRuntime(1253): Caused by: java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called. 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.widget.ListView.addHeaderView(ListView.java:256) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.widget.ListView.addHeaderView(ListView.java:279) 10-20 02:38:38.342: E/AndroidRuntime(1253): at com.example.mycoursetimetable.MyCourses.onCreate(MyCourses.java:30) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-20 02:38:38.342: E/AndroidRuntime(1253): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) 10-20 02:38:38.342: E/AndroidRuntime(1253): ... 11 more 10-20 02:38:38.382: I/dalvikvm(1253): threadid=7: reacting to signal 3 10-20 02:38:38.382: E/dalvikvm(1253): Unable to open stack trace file '/data/anr/traces.txt': Permission denied 10-20 02:38:47.463: I/Process(1253): Sending signal. PID: 1253 SIG: 9

activity_my_courses

<LinearLayout 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:orientation="vertical"
    android:id="@+id/main" >

    <Button
        android:id="@+id/labelAddCourseButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="addCourseButton"
        android:padding="10dp"
        android:text="@string/CourseName" />

</LinearLayout>

listcourses

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >



    <TextView
        android:id="@+id/labelModuleCode"
        android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_marginLeft="10dp"
        android:text="@string/CourseName"
        android:textSize="10dp" />

     <TextView
        android:id="@+id/labelCourseType"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/CourseType"
        android:layout_marginLeft="10dp"
        android:textSize="10dp" />
</LinearLayout>

Code

public class MyCourses extends ListActivity {

    static final String TEST = "com.example.mycoursetimetable.TEST";
    String [] MODULE;

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

        LinearLayout main = (LinearLayout)this.findViewById(R.id.main);
        MODULE = getResources().getStringArray(R.array.module);
        setListAdapter(new ListArrayAdapter(this,MODULE));
        }



        public void addCourseButton (View addCourseButton) 
        {
         Intent intent = new Intent(this,AddCourse.class);
         startActivity(intent);
        }

        protected void onListItemClick(ListView l, View v, int position, long id)
        {
          super.onListItemClick(l, v, position, id);


        try {
            Class test = Class.forName("com.example.MyCourseTimeTable.AddCourse");
            Intent intent = new Intent(MyCourses.this, test);

            TextView textView = (TextView) v.findViewById(R.id.labelModuleCode);
            String module = textView.getText().toString();


            intent.putExtra(TEST,module);
            startActivity(intent);
            }   
                catch (ClassNotFoundException e)
                {
                e.printStackTrace();
                }

        }

}

class ListArrayAdapter extends ArrayAdapter<String> 
{
    //  You only need one copy of LayoutInflater
    private final LayoutInflater inflater;

    //create the ArrayAdpater
    public ListArrayAdapter(Context context, String[] test) 
    {
        super(context, R.layout.activity_my_courses, test);
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        ViewHolder holder;
        if(convertView == null) {


            // Inflate the layout that you want for each row


            convertView = inflater.inflate(R.layout.listcourses, parent, false);

            holder = new ViewHolder();
            holder.code = (TextView) convertView.findViewById(R.id.labelModuleCode);
            holder.type = (TextView) convertView.findViewById(R.id.labelCourseType);

            // Add a link for your button as well and define its OnClickListener here to, eventually...

            convertView.setTag(holder);
        }
        else 
            holder = (ViewHolder) convertView.getTag();

        String module = getItem(position);
        //set the text to the string values based on position
        holder.code.setText(module);

        //return the layout
        return convertView;
    }

    class ViewHolder {
        TextView code;
        TextView type;
    }
}
Calgar99
  • 1,670
  • 5
  • 26
  • 42
  • at the beginning of onCreate() method, you're not calling setContentView() method..so no wonder you cannot find your main LinearLayout – Tomislav Novoselec Oct 31 '12 at 14:58
  • It's not clear what you're trying to do. You aren't making use of the `main` variable that you are assigning in `onCreate`. Also, the layout `activity_my_courses` cannot be used as is as the layout for a `ListActivity`. It needs to have a `ListView` with attribute `android:id="@android:id/list"`. – Ted Hopp Oct 31 '12 at 15:00

2 Answers2

3

Rather than trying to define your own activity layout, you can use something like this:

public class MyCourses extends ListActivity {

    static final String TEST = "com.example.mycoursetimetable.TEST";
    String [] MODULE;

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

        MODULE = getResources().getStringArray(R.array.module);
        getListView().addHeaderView(getHeader()); // must come before next line
        setListAdapter(new ListArrayAdapter(this,MODULE));
    }

    private View getHeader() {
        LayoutInflater inflater =
            (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        return inflater.inflate(R.layout.listcourses, null);
    }
    . . .
}

That will make the view defined in layout/listcourses.xml the header for the list.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Hi Ted, I tired an approach similar to this but when I run the activity in the emulator I get an error displaying the application has stopped unexpectedly. – Calgar99 Oct 31 '12 at 15:27
  • Ive added the Logcat output to the my main post. – Calgar99 Oct 31 '12 at 15:38
  • @user1544223 - Ah. That was my mistake. Reverse the order of the calls to `addHeaderView` and `setListAdapter`. I've fixed my code to show an order that should work. – Ted Hopp Oct 31 '12 at 15:44
  • Thank you so much, I've spent ages trying to figure this out. – Calgar99 Oct 31 '12 at 15:47
0

I guess you need to have a <ListView/> below you textviews in xml file android id should be default android:id\list secondly you need to do setContentView(YOUR LAYOUT FILE) in your onCreate()

Just Variable
  • 892
  • 10
  • 19