Multicolumn ListView Android

后端 未结 3 1639
小鲜肉
小鲜肉 2021-01-03 15:46

i am creating a leaderboard, highscore list for my application. I want to display the data in 4 columns, Rank, Name, Creator, Score and populate them accordingly by a list o

相关标签:
3条回答
  • 2021-01-03 16:21

    Finally found a solution. I Had the same question as someone new to Android and Xamarin for Android. To be clear - I'm using Xamarin Studio, and Xamarin for Android written in C#.

    Although it seems like the SimpleCursorAdapter can accommodate multiple fields, when binding to something like the SimpleListItem only one field gets used.

    I first tried this:

            string[] fromColumns = new string[]{ "checkListName","checkListDesc" };
            int[] toControlIDs = new int[] {Android.Resource.Id.Text1, Android.Resource.id.Text1};
    
            try{
                listView.Adapter = new SimpleCursorAdapter(this,Android.Resource.Layout.SimpleListItem1 , c, fromColumns, toControlIDs, 0);         
            }
            catch(SQLiteException e){
                Console.WriteLine ("whoops, " + e.Message.ToString ());
            }
    

    But all I ever got was the last field in the cursor row.

    I learned that a CUSTOM LISTVIEW was needed. Following are code files for four files:

    1. MainActivity.cs
    2. myList.xml
    3. Main.axml
    4. PreFloat.cs (this is the database part)

    I have included all of this to provide as much as possible a completely working sample that is as close to real life as possible.

    Here is MainActivity.cs which sets a content view, uses a cursor to get data from a SQLite database, and defines a

    using System;
    
    using Android.App;
    using Android.Content;
    using Android.Database;
    using Android.Database.Sqlite;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Android.OS;
    
    namespace Darjeeling
    {
    [Activity (Label = "Darjeeling", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {       
    
        ListView listView;
        Darjeeling.PreFloatDatabase pdb;
        ICursor c;
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
    
            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);
            listView = FindViewById<ListView> (Resource.Id.listView1);
            pdb = new PreFloatDatabase (this);
            //  Assign the cursor to a query
            c = pdb.ReadableDatabase.RawQuery ("select * from checkLists", null);
            StartManagingCursor (c);
            // A ListView needs an adapter -- so we'll assign our instantiated listView's adapter to our customized adapter called HomeScreenCursorAdapter.
            listView.Adapter = (IListAdapter)new HomeScreenCursorAdapter (this,c);
        }
        //  End onCreate method
    
        // This handles the cursor when the user is done with the activity
        protected override void OnDestroy()
        {
            StopManagingCursor(c);
            c.Close ();
            base.OnDestroy();
        }
        //  Here's the magic -- 
        public class HomeScreenCursorAdapter : CursorAdapter {
            Activity context;
            public HomeScreenCursorAdapter(Activity context, ICursor c)
                : base (context, c)
            {
                this.context = context;
            }
            //  This overridden BindView method is going to let me assign TextView controls that I've set up in an XML file, to specific fields in the cursor.  
            public override void BindView(View view, Context context, ICursor cursor)
            {
                var txtCheckListName = view.FindViewById<TextView> (Resource.Id.txtCheckListName); //(Android.Resource.Id.Text1);
                var txtCheckListDesc = view.FindViewById<TextView> (Resource.Id.txtCheckListDesc); //(Android.Resource.Id.Text2); 
    //  For testing purposes, I first assigned static values to txtCheckListName and txtCheckListDesc, for instance, txtCheckListName.Text = "Hello";  and txtCheckListDesc.Text = "World"; 
                txtCheckListName.Text = cursor.GetString (3);
                txtCheckListDesc.Text = cursor.GetString (4);
            }
            //  This overridden View inflates each row (I think).  This could inflate a built-in ListView control like SimpleListItem, OR, in this case, it references a custom written XML file called myList.
            public override View NewView(Context context, ICursor cursor, ViewGroup parent)
            {
                return this.context.LayoutInflater.Inflate (Resource.Layout.myList, parent, false);
            }
        }
    }
    

    }

    Here's the Main.axml file:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/linearLayout1"
    android:minWidth="25px"
    android:minHeight="25px">
    <ListView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/listView1" />
    </LinearLayout>
    

    And finally, the myList.xml file which is essentially the definition of the ListView row:

    <?xml version="1.0" encoding="utf-8"?>
    <!---<FrameLayout   xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="200dp"
                android:layout_height="match_parent"
                android:background="#FF0000FF">
    -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/linearLayout1"
    android:minWidth="25px"
    android:minHeight="25px">
    <TextView
        android:id="@+id/txtCheckListName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="" />
    <TextView
        android:id="@+id/txtCheckListDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:text="" />
    </LinearLayout>
    <!---</FrameLayout>-->
    

    And here's the database file:

    using System;
    using Android.Database.Sqlite;
    using Android.Content;
    
    namespace Darjeeling {
    class PreFloatDatabase : SQLiteOpenHelper {
        public static readonly string create_checkLists_table = "create table if   not exists checkLists([_id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,  checkListID INTEGER, checkListType INTEGER, checkListName TEXT, checkListDesc TEXT);";
        public static readonly string DatabaseName = "prefloat.db";
        public static readonly int DatabaseVersion = 1;
        public PreFloatDatabase (Context context) : base (context, DatabaseName, null, DatabaseVersion){        }
    
        public override void OnCreate(SQLiteDatabase db){
            //  fire the statement that creates the checkLists table
            try{
            db.ExecSQL (create_checkLists_table);           
            //  Now pre-fill the checkLists table
                db.ExecSQL ("insert into checkLists (checkListID, checkListType,  checkListName, checkListDesc) values (0, 0, 'Widgeon','Widgeon Daysailer');");
                db.ExecSQL ("insert into checkLists (checkListID, checkListType, checkListName, checkListDesc) values (1, 1, 'Widgeon','Widgeon Daysailer');");
                db.ExecSQL ("insert into checkLists (checkListID, checkListType, checkListName, checkListDesc) values (2, 0, 'Bowrider', 'Mo Motor, Mo Fun');");
                db.ExecSQL ("insert into checkLists (checkListID, checkListType, checkListName, checkListDesc) values (3, 1, 'Bowrider', 'Mo Motor, Mo Fun');");
                db.ExecSQL ("insert into checkLists (checkListID, checkListType, checkListName, checkListDesc) values (4, 0, 'HobieCat','Hang yer ass out fun');");
                db.ExecSQL ("insert into checkLists (checkListID, checkListType, checkListName, checkListDesc) values (5, 1, 'HobieCat','Hang yer ass out fun');");
            }
            catch(SQLiteException e){
                Console.WriteLine ("Problem with the database " + e.Message.ToString ());
            }
    
        }
        public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
            throw new NotImplementedException ();
        }
    
    } // matches with class PreFloatDatabase
    } // matches with namespace Darjeeling
    

    Questions: SHOULD a SimpleListItem control have more than a single field or at most a checkbox control and label? Should a grid control be used instead?

    Alternatives: Instead of doing all these shenanigans, wouldn't it be easier to simple concatenate the needed values using SQL? Especially since coordinating the positioning of two text controls might be too complicated.

    Full Disclosure: This code is an amalgam of code I read in other posts and forums, and customized to fit my own particular requirements.

    0 讨论(0)
  • 2021-01-03 16:23

    You can easily done it with defining Custom ListView.

    For defining custom listview, just define a custom row layout file with 4 textview in horizontal manner. Now inflating this layout file inside the custom adapter of listview, for that you need to override getView() method and inflate that row layout file.

    Update: Just check this tutorial to define custom listview, but make sure you use this tutorial by defining a custom row layout file with 4 horizontal textview.

    Here is the row_layout.xml file:

    <LinearLayout 
        android:id="@+id/relativeLayout1" 
        android:layout_height="fill_parent" 
        android:layout_width="fill_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">
    
        <TextView
            android:id="@+id/FirstText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="First"
            android:layout_weight="1">
        </TextView>
    
        <TextView
            android:id="@+id/SecondText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Second"
            android:layout_weight="1">
        </TextView>
    
        <TextView
            android:id="@+id/ThirdText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Third"
            android:layout_weight="1">
        </TextView>
    
        <TextView
            android:id="@+id/FourthText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Fourth"
            android:layout_weight="1">
        </TextView>
    </LinearLayout>
    
    0 讨论(0)
  • 2021-01-03 16:30

    Each item in the listview is inflated from a layout file. In the layout file, you can add four textview horizontally align to each other. For more information you need to focus on EfficientAdapter which leads to custom ListView.

    0 讨论(0)
提交回复
热议问题