【问题标题】:Can't get custom ListAdapter to work无法让自定义 ListAdapter 工作
【发布时间】:2012-10-25 21:16:56
【问题描述】:

我已经遵循了各种“如何”示例(或者我认为是这样),但我仍然无法让我的自定义 ListAdapter 工作。我有一个包含字符串的列表视图对话框,这些字符串是对对象数组(“Notam”类)的引用。我想根据引用对象的一个​​属性来设置每个列表项的颜色。

(在你阅读我的代码之前,我有一个怪癖,大括号必须对齐,否则我看不到块在哪里。我不喜欢在同一行末尾放置左大括号的约定.)

这是自定义类的代码(作为测试,我试图将每个项目的文本颜色设置为洋红色):

private class GotoAdapter extends ArrayAdapter<String>
{
    private ArrayList<String> items;

    public GotoAdapter(Context context, int textViewResourceId, ArrayList<String> items)
    {
        super(context, textViewResourceId, items);
        this.items = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View v = convertView;
        if (v == null)
        {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.goto_row, null);
        }
        String s = items.get(position);
        if (s != null)
        {
            TextView tt = (TextView) v.findViewById(R.id.text1);
            if (tt != null)
            {
                String s1 = (String)tt.getText(); // this is always an empty string!
                tt.setTextColor(0xFF00FF); // this has no effect!
            }
        }
        return v;
    }
}

使用这个派生类时,String s 有如预期显示的文本(除了在屏幕上看不到),但是返回的TextView中的文本始终是空字符串,设置颜色没有效果.

这是在我的主视图中单击“转到”按钮时显示对话框的代码:

mGotoButton.setOnClickListener(new View.OnClickListener()
{
    public void onClick(View v)
    {
        // The pre-loaded array gets round a problem which I read about somewhere else
        // (the ArrayList gets cleared again below)
        String[]    array = {"one", "two", "three"};
        ArrayList<String> lst = new ArrayList<String>();
        lst.addAll(Arrays.asList(array));

        // custom dialog
        final Dialog dialog = new Dialog(context);

        dialog.setContentView(R.layout.goto_dialog);
        dialog.setTitle("Choose Notam");

        // Create the list view and adapter
        final ListView list = (ListView) dialog.findViewById(R.id.goto_list);

        // If I replace this reference to my custom adapter...
        final GotoAdapter adapter = new GotoAdapter
                (mContext, R.layout.goto_row, lst);

        // ... with this normal one, everything works!
        // (but of course now I can't get access to the objects.)
//      final ArrayAdapter<String> adapter = new ArrayAdapter<String>
//              (mContext, R.layout.goto_row, lst);

        list.setAdapter(adapter);

        // Populate the adapter
        adapter.clear();        // first clear the silly preset strings

        // Notam is my object class.
        // Spine.mNotamsDisplayed is a public static NotamArray.
        // class NotamArray extends ArrayList<Notam>
        // Spine is my main activity where I keep my global (app-wide) stuff.

        for (Notam notam : Spine.mNotamsDisplayed)
        {
            // This gets the reference string from the Notam object.
            // This is what goes into the list.
            String s = notam.getReference();
            adapter.add(s);
        }

        // Sort into alphabetical order
        adapter.sort(new Comparator<String>()
        {
            public int compare(String arg0, String arg1)
            {
                return arg0.compareTo(arg1);
            }
        });

        list.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            public void onItemClick(AdapterView<?> a, View v, int pos, long id)
            {
                String  s;
                int     i;

                s = (String)a.getItemAtPosition(pos);

                // This static function returns the index in Spine.mNotamsDisplayed
                // which is referenced by the reference string s.
                // I have to do this because I lost the one-for-one correlation of page
                // indexes with list view entries when I did the sort.
                i = NotamArray.findNotamIndexByReference(Spine.mNotamsDisplayed, s);
                if (i >= 0)
                {
                    // This is what the Goto button and dialog is all about: this
                    // just moves my main view's pager to the page that was selected.
                    mPager.setCurrentItem(i);
                }
                dialog.dismiss();
            }
        });

        dialog.show();
    }
});

这是我用于对话框的 xml (goto_dialog.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ListView 
        android:id="@+id/goto_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>    

这是我的列表视图行的 xml (goto_row.xml):

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#00FF00"
    android:gravity="center_vertical"
     android:textAppearance="?android:attr/textAppearanceMedium"
    android:padding="2dp" 
    android:textSize="20dp"
/>

(我将文本颜色设置为绿色,因此如果我使用标准列表视图适配器,我可以看到该位正在工作。(果然每个条目的文本都是绿色的。但是,如果我使用我的自定义适配器,虽然它在那里 - 我假设黑底黑字。)

一定有人能发现我犯的一个小错误——拜托!

【问题讨论】:

  • 当没有文本显示时,您不会看到任何 text 颜色。使用setText()-方法根据您当前的位置设置文本(在您当前从TextView检索空文本的行中)。
  • Lukas,我认为视图是用来显示文本的,因此惊讶地发现它是空的。我会听从你的建议,看看是否能解决我的问题。但是,如果屏幕上的文本不是来自视图,我看不出设置它和更改它的颜色会如何影响任何事情。顺便说一句,您有一个著名的计算名称 - 有什么关系吗?
  • @Lukas Knuth 错过了 @ 标记。
  • @LukasKnuth 这是故事的一部分 - 谢谢,但请参阅我自己的答案,我发现我一直认为一定是一个微不足道的错误。

标签: android listview adapter listadapter


【解决方案1】:

根据我的阅读,您似乎希望将每个列表项的文本颜色设置为与数组中的颜色相匹配。

我想根据被引用对象的一个​​属性来设置每个列表项的颜色。

但是,您的初始数组设置为

String[] array = {"one", "two", "three"};

因此,当您稍后根据数组动态设置文本颜色时,这将导致问题。但我确定您打算稍后更改。

当您使用标准数组适配器时,它只是将数组中的项目显示为文本,这就是为什么:

如果我使用标准列表视图适配器。 (果然每个条目的文本都是绿色的。但是,如果我使用自定义适配器,则看不到任何文本

要查看您的自定义适配器是否正常工作(更改颜色),您可以从 goto_row.xml 文件的 TextView 中添加一行开始:

android:text="Test String"

现在它将以不同的颜色显示“测试字符串”,并且

String s1 = (String)tt.getText();

上面一行会得到“测试字符串”

【讨论】:

  • 以一、二、三字符串数组开头的 3 行是故意的。必须以这种方式初始化 lst 变量,否则在适配器中添加和删除项目会引发 UnsupportedOperationException。这个问题在 StackExchange 的其他地方有解释——我搜索过但找不到了。我认为这是因为 lst 在其他方面是不可变的。此外,您的初始行也不完全正确。我想要的颜色是由底层对象的一个​​属性决定的,也就是它的状态。 @tigerpenguin
【解决方案2】:

我发现了我在问题末尾暗示的小错误。就是自定义适配器中的这一行:

tt.setTextColor(0xFF00FF);

似乎 0xFF00FF 不是一个有效的颜色值,这就是为什么我在屏幕上什么也没看到。 将其更改为:

tt.setTextColor(Color.rgb(255, 0, 255);

修复了问题,将默认的绿色改为洋红色,并且我可以将文本设置为我想要的值。所以我现在可以将各个行的颜色设置为他们需要的颜色。

感谢@LukasKnuth 和@tigerpenguin 为我指明了正确的方向。

【讨论】:

  • 其实,0xFF00FF 一个有效的颜色值,但是完全透明,所以什么都看不到。 0xFFFF00FF 会显示为洋红色。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
相关资源
最近更新 更多