Android适配器和适配器视图_适配器视图引用

步骤 2:创建资源文件
创建一个新的布局 XML 文件,其根元素为 ,并将其命名为项.xml。将“大文本”微件拖放到其中,并将其属性的值设置为cheese_name。布局 XML 文件应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_horizontal_margin">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/cheese_name" />
</LinearLayout>

步骤 3:创建适配器
在活动中,使用类的构造函数创建类的新实例。作为其参数,传递资源文件的名称、的标识符和对数组的引用。适配器现在已准备就绪。

ArrayAdapter<String> cheeseAdapter = 
    new ArrayAdapter<String>(this,
        R.layout.item,
        R.id.cheese_name,
        cheeses
    );

4. 创建列表

要显示可垂直滚动的项目列表,可以使用微件。要将小部件添加到活动中,可以将其拖放到活动的布局 XML 文件中,也可以使用 Java 代码中的构造函数创建小组件。

ListView cheeseList = new ListView(this);

setContentView(cheeseList);

若要将其绑定到我们在上一步中创建的适配器,请调用如下所示的方法。

cheeseList.setAdapter(cheeseAdapter);

如果现在运行应用,则应该能够以列表的形式查看数组的内容。

5. 创建网格

要显示可垂直滚动的项目二维网格,可以使用微件。两者都是抽象类的子类,它们有许多相似之处。因此,如果您知道如何使用其中一个,那么您也知道如何使用另一个。

使用类的构造函数创建一个新实例,并将其传递给活动的方法。

GridView cheeseGrid = new GridView(this);
setContentView(cheeseGrid);

若要设置网格中的列数,请调用其方法。我将把它做成一个两列的网格。

cheeseGrid.setNumColumns(2);

通常,您希望使用 、 和 方法来调整列的宽度和之间的间距。请注意,这些方法使用像素作为其单位。setColumnWidth()setVerticalSpacing()setHorizontalSpacing()

cheeseGrid.setColumnWidth(60);
cheeseGrid.setVerticalSpacing(20);
cheeseGrid.setHorizontalSpacing(20);

现在,您可以使用该方法将 绑定到我们之前创建的适配器。

cheeseGrid.setAdapter(cheeseAdapter);`

再次运行应用以查看外观。

6. 添加事件侦听器

可以侦听适配器视图中项目的单击和长单击事件。例如,让我们将单击事件侦听器添加到 GridView

创建实现接口的匿名类的新实例,并将其传递给对象的方法。安卓工作室会为接口的方法自动生成一个存根。您会注意到,该方法的参数包含一个整数,用于指定列表项的位置。您可以使用此整数来找出用户单击的数据集中的哪个项目。AdapterView.OnItemClickListenersetOnItemClickListener()GridViewonItemClick()

下面的代码演示如何在每次单击 中的项时将简单消息显示为小吃栏。

cheeseGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView,
                            View view, int position, long rowId) {
 
        // Generate a message based on the position
        String message = "You clicked on " + cheeses[position];
 
        // Use the message to create a Snackbar
        Snackbar.make(adapterView, message, Snackbar.LENGTH_LONG)
                .show(); // Show the Snackbar
    }
});

如果运行应用并单击网格中的任意项目,屏幕底部将显示一条消息。请注意,您可以使用相同的代码来侦听。

7. 扩展ArrayAdapter

在它生成的对象的布局中只能处理一个小部件。要拓宽它的功能,你必须扩展它。但是,在我们这样做之前,让我们创建一个稍微复杂的数据集。

假设我们的数据集包含以下类的对象,而不是字符串:

static class Cheese {
    String name;
    String description;
 
    public Cheese(String name, String description) {
        this.name = name;
        this.description = description;
    }
}

这是我们将使用的数据集:

Cheese[] cheeses = {
        new Cheese("Parmesan", "Hard, granular cheese"),
        new Cheese("Ricotta", "Italian whey cheese"),
        new Cheese("Fontina", "Italian cow's milk cheese"),
        new Cheese("Mozzarella", "Southern Italian buffalo milk cheese"),
        new Cheese("Cheddar", "Firm, cow's milk cheese"),
};

如您所见,该类包含两个字段和 。要在列表或网格中显示这两个字段,项目的布局必须包含两个微件。

创建一个新的布局 XML 文件并将其命名为custom_item.xml。向其添加“大文本”和“小文本”构件。将第一个小部件的属性设置为cheese_name将第二个小部件的属性设置为cheese_description。布局 XML 文件的内容现在应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_horizontal_margin">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/cheese_name" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:id="@+id/cheese_description" />
</LinearLayout>

还必须能够处理两个小部件。重新访问您的活动,创建一个扩展该类的新匿名类,并重写其方法。确保将数组作为参数传递给其构造函数。

ArrayAdapter<Cheese> cheeseAdapter = 
        new ArrayAdapter<Cheese>(this, 0, cheeses) {
            @Override
            public View getView(int position,
                                View convertView,
                                ViewGroup parent) {
 
            }
        };

在方法内部,必须将参数用作数组的索引,并在该索引处获取项。getView()position

Cheese currentCheese = cheeses[position];

该方法的第二个参数使我们能够重用对象。如果忽略它,适配器视图的性能将很差。首次调用该方法时, 是 。必须通过扩充指定列表项布局的资源文件来初始化它。为此,请使用该方法获取对 的引用并调用其方法。

// Inflate only once
if(convertView == null) {
    convertView = getLayoutInflater()
                    .inflate(R.layout.custom_item, null, false);
}

此时,您可以使用 来获取对布局内小部件的引用,并调用它们的方法以使用数组中的数据对其进行初始化。

TextView cheeseName = 
    (TextView)convertView.findViewById(R.id.cheese_name);
TextView cheeseDescription = 
    (TextView)convertView.findViewById(R.id.cheese_description);
 
cheeseName.setText(currentCheese.name);
cheeseDescription.setText(currentCheese.description);

最后,返回,以便它可用于填充与适配器关联的任何适配器视图。

return convertView;

8. 使用视图支架

适配器视图重复调用该方法以填充自身。因此,您必须尝试尽量减少在其中执行的操作数。getView()

在上一步中,您可能已经注意到,即使我们确保列表项的布局只膨胀一次,每次调用该方法时都会调用该方法,该方法会消耗许多 CPU 周期。

为了避免这种情况并提高适配器视图的性能,我们需要将方法的结果存储在对象中。为此,我们可以使用视图持有者对象,它只不过是一个类的对象,可以存储布局中存在的小部件。

由于布局具有两个构件,因此视图持有者类还必须具有两个构件。我已将类命名为“视图持有者”。

static class ViewHolder{
    TextView cheeseName;
    TextView cheeseDescription;
}

在该方法中,在放大布局后,现在可以使用该方法初始化视图持有者对象。

ViewHolder viewHolder = new ViewHolder();
viewHolder.cheeseName =
        (TextView)convertView.findViewById(R.id.cheese_name);
viewHolder.cheeseDescription =
        (TextView)convertView.findViewById(R.id.cheese_description);

要将视图持有者对象存储在 中,请使用其方法。convertViewsetTag()

// Store results of findViewById
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值