首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更改列表项选择的视图属性

更改列表项选择的视图属性
EN

Stack Overflow用户
提问于 2012-03-13 00:20:01
回答 3查看 1.6K关注 0票数 5

我有一个包含自定义行的ListView。此自定义行具有以下UI元素

  1. ImageView imageView1,imageView2
  2. TextView textview1,textView2,textView3

要求是,只要选择了列表行,就会发生以下更改

imageView1背景,颜色改变

imageView1颜色变了

textview1的颜色,大小和字体都是变化的

textview2颜色,大小已更改

textview3颜色,大小已更改

最好的设计方法是什么?

AFAIK我们不能在选择器中应用样式。是否有更好的方法来处理这个问题,而不是在java代码中处理呢?

我们有可以在Listview上设置的setOnItemSelectedListener,它将具有以下回调方法:

i) onItemSelected

(二) onNothingSelected

但是,没有回调方法可以提供失去焦点的项的详细信息。这里是做出改变的更好的地方吗?

提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-21 14:56:13

我认为您在这里要做的是创建一个复合控制。您可以在示例//ApiDemos子目录中的SDK目录中找到一个示例(如果没有这些目录,您可能希望下载Android源 )。

我要做的是创建一个类,它继承自定义行使用的任何类型的布局。让我们假设这个例子是一个LinearLayout。在子类构造函数中,可以从资源中膨胀布局,找到subViews并将它们附加到实例变量,并将LinearLayout返回给调用者。

在这个子类中,您可以重写setSelected并以任何您想要的方式操作subViews。

下面是我根据你的帖子描述的一个例子:

代码语言:javascript
运行
复制
public class MyCustomLayout extends LinearLayout {
    public ImageView imageView1;   // These are public since you likely want
    public ImageView imageView2;   // to set them in your Adapter.
    public TextView textView1;
    public TextView textView2;
    public TextView textView3;

    public MyCustomLayout(Context ctxt) {
        super(ctxt);

        // The call below attaches the items in the mycustomlayout.xml file to this
        // instance, which serves as the root element in the layout.
        LayoutInflater.from(ctxt).inflate(R.layout.mycustomlayout, this, true);

        imageView1 = (ImageView)findViewById(R.id.imageview1);
        imageView2 = (ImageView)findViewById(R.id.imageview2);
        textView1 = (TextView)findViewById(R.id.textview1);
        textView2 = (TextView)findViewById(R.id.textview2);
        textView3 = (TextView)findViewById(R.id.textview3);
    }

    @Override
    public void setSelected(boolean selected) {
        super.setChecked(selected);
        if (selected) {
            imageView1.setBackgroundColor(0xFFFF0000); // whatever color you want
            // Do all the rest of the setting of your subviews here for
            // the case when the row is selected.
        } else {
            imageView1.setBackgroundColor(0xFF000000); // whatever color you want
            // Do all the rest of the setting of your subviews here for
            // the case when the row is not selected
        }
    }
}

现在,在mycustomlayout.xml文件中,您希望使用<merge>标记,这样就不会创建不必要的布局:

代码语言:javascript
运行
复制
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/imageview1" />
    <ImageView
        android:id="@+id/imageview2" />
    <TextView
        android:id="@+id/textview1" />
    <TextView
        android:id="@+id/textview2" />
    <TextView
        android:id="@+id/textview3" />
</merge>

显然,我已经省略了上述子视图的所有配置,但是您应该了解如何设置XML文件。如果您不想愚弄XML和LayoutInflater,也可以在代码中这样做。您可以在Android博客上查看这篇有用的博客文章,该博客最后讨论了一个类似的案例。

然后,在Adapter的getView中,您只需创建(或回收) MyCustomLayout实例,设置它们,并让框架负责跟踪哪些行被选中,哪些没有被选中。

票数 2
EN

Stack Overflow用户

发布于 2012-03-16 04:56:12

我有种粗野的方式..。但过程很重..。一旦一项被选中,刷新你的列表视图。只对选定的项目,它应该显示特定的字体等.并将所选项的id存储在某个变量中以匹配它,同时在适配器中填充视图.

票数 0
EN

Stack Overflow用户

发布于 2012-03-20 06:25:57

霍特马尼什

我不知道你所说的最有效的方式是什么意思。有许多方法是非常迅速的,但它往往取决于你事先知道什么,什么你不知道。我们还必须认识到,动态视图属性被严重误解,但是尽管流行神话,但效率却很高。谷歌的员工在用户界面开发方面做得非常出色。

如果您提前知道它,您可以为每个视图创建一个StateListDrawable,并在运行适配器时将其应用于每个视图。

要构建您的StateListDrawable,请创建一个:

代码语言:javascript
运行
复制
StateListDrawable _drawStates;

然后,对于每个状态,添加所需的可绘制性:

代码语言:javascript
运行
复制
_drawStates.add(new int[] {android.R.attr.state_pressed}, _newImage);

这与适配器的getView()方法中的以下行一样简单:

代码语言:javascript
运行
复制
v.setBackgroundDrawable(_drawStates);

或者,您可以根据所选内容动态地更改背景。这可以在OnListItemClick()中完成。你看,OnListItemClick()会给出被点击的确切视图。一旦您有了它,您就可以通过它的id找到子对象,并更改它的属性和invalidate()它。我经常用这个把戏。节省了很多内存,但我并没有做任何真正的处理器密集型工作。您可以在这里更改几乎任何属性,而无需进行几乎任何处理。下面是一个示例:

代码语言:javascript
运行
复制
@Override protected void onListItemClick(final ListView inList, final View v, final int atPos, final long rowID)
{//Get the Child, set the properties
    ImageView _img = (ImageView)(v.findViewById(R.id.app_package));
    _img.setBackgroundColor(myClickedColor);
    _img.invalidate();  // <---- BEST Option
// ... OR ...
    v.invalidate();     // <---- 2nd Best Option
// ... OR ...
    inList.invalidate();  // <---- Last resort or specialized implementation
}

重要的是要注意,当涉及到背景颜色时,动态地这样做有一些警告。你必须把孩子从点击的视图中..。不是ListView。第二,当更改背景色时,实际上是在更改背景绘图。这意味着所有其他“有状态”属性都会消失,您必须手动将其更改(如果您希望它开始的话)。

现在,一种更流行但不太灵活的方法是使用XML构建StateListDrawable。在Android开发者的网站上有很多资源可以学习如何做到这一点。

希望这有帮助,FuzzicalLogic

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9676689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档