Calgar99
Calgar99

Reputation: 1688

Android: How to combine an inflated layout and non inflated layout?

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;
    }
}

Upvotes: 2

Views: 354

Answers (2)

Ted Hopp
Ted Hopp

Reputation: 234795

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.

Upvotes: 3

Just Variable
Just Variable

Reputation: 877

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()

Upvotes: 0

Related Questions