【问题标题】:Multicolumn ListView Android多列ListView Android
【发布时间】:2011-10-21 11:19:36
【问题描述】:

我正在为我的应用程序创建一个排行榜、高分列表。我想在 4 列中显示数据,Rank、Name、Creator、Score 并通过对象列表相应地填充它们。我想在列表上一次显示 5 个项目,列表上共有 20 个项目,使列表可滚动。我找不到合适的方法来解决这个问题。由于我的工作截止日期快到了,如果我能得到一个关于“如何做”的快速指南会很棒。

谢谢一百万:)

【问题讨论】:

标签: android listview


【解决方案1】:

您可以通过定义自定义 ListView 轻松完成。

要定义自定义列表视图,只需以水平方式定义一个具有 4 个文本视图的自定义行布局文件。现在在 listview 的自定义适配器中扩展此布局文件,为此您需要覆盖 getView() 方法并扩展该行布局文件。

更新: 只需检查此tutorial 即可定义自定义列表视图,但请确保通过定义具有 4 个水平文本视图的自定义行布局文件来使用本教程。

这是 row_layout.xml 文件:

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

【讨论】:

  • 你能把我链接到一个文本或一个合适的教程,你的方法看起来很可靠,我愿意学习它,但是膨胀没有意义,它是一种方法还是什么?
  • 谢谢..我刚刚看完并理解了博客,现在尝试实现它..
  • @MohammadUmairKhan 太好了,创建自定义适配器是一次性练习。因此,请确保您做到完美。
  • 救命稻草 .. paresh .. 你让我的一天变得轻松!!感谢 A GAZILLION [对不起帽子,我很高兴 :) ]
【解决方案2】:

终于找到了解决办法。我和 Android 和 Xamarin for Android 的新手有同样的问题。明确一点 - 我使用的是 Xamarin Studio,以及用 C# 编写的 Xamarin for Android。

虽然看起来 SimpleCursorAdapter 可以容纳多个字段,但当绑定到诸如 SimpleListItem 之类的东西时,只会使用一个字段。

我第一次尝试这个:

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

但我得到的只是光标行中的最后一个字段。

我了解到需要自定义列表视图。以下是四个文件的代码文件:

  1. MainActivity.cs
  2. myList.xml
  3. Main.axml
  4. PreFloat.cs(这是数据库部分)

我包含所有这些是为了提供尽可能接近真实生活的完整工作示例。

这里是 MainActivity.cs,它设置了一个内容视图,使用游标从 SQLite 数据库中获取数据,并定义了一个

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

}

这是 Main.axml 文件:

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

最后是 myList.xml 文件,它本质上是 ListView 行的定义:

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

这是数据库文件:

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

问题: 应该 SimpleListItem 控件有多个字段或最多有一个复选框控件和标签? 应该改用网格控件吗?

替代方案: 与其做所有这些恶作剧,不如使用 SQL 简单地连接所需的值不是更容易吗?特别是因为协调两个文本控件的定位可能太复杂了。

全面披露: 这段代码是我在其他帖子和论坛中阅读的代码的混合体,并根据我自己的特定要求进行了定制。

【讨论】:

    【解决方案3】:

    列表视图中的每个项目都是从布局文件中扩展而来的。在布局文件中,您可以添加四个彼此水平对齐的textview。有关更多信息,您需要关注导致自定义 ListView 的 EfficientAdapter。

    【讨论】:

      猜你喜欢
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多