【问题标题】:Filling listview row's color to some percentage将列表视图行的颜色填充到某个百分比
【发布时间】:2015-06-22 18:33:20
【问题描述】:

我正在尝试用颜色将列表视图的行填充到某个百分比。 这应该在用户单击任何列表项后完成。

很难解释,请看下图:

请告诉我如何进行,我不知道如何实施。我正在考虑在用户点击事件后添加一个视图并设置此视图的背景颜色。

如果有其他方法,请告诉我。

谢谢

【问题讨论】:

  • 只需使用 ClipDrawable 并将其设置为项目的背景

标签: android android-layout listview android-listview android-drawable


【解决方案1】:

您可以为每个项目使用此布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="100"
        android:baselineAligned="false">
        <View
            android:layout_weight="50"
            android:background="#0080FF"
            android:layout_width="0dp"
            android:layout_height="match_parent"/>
    </LinearLayout>

    <TextView
        android:text="@string/hello_world"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center_vertical"/>
</RelativeLayout>

然后通过修改最内层View的权重属性,可以指定颜色宽度百分比。这可以通过修改ListView 适配器内部的视图LayoutParams 来完成。 SO上有很多关于自定义适配器和LayoutParam的教程。

它的外观如下:

【讨论】:

    【解决方案2】:

    我认为下面描述了一个选项:

    我会创建一个列表视图,对于列表中的每个项目,我会创建两个视图:

    1. 一个 TextView(显示文本选项)-> 默认可见
    2. 一个视图(如果用户在列表中单击则绘制进度)-> 默认为不可见。

    注意:这个带有进度的简单视图对于 TextView 将具有相同的高度。它用背景颜色(例如蓝色)完全着色。然后,您可以通过设置其权重(从 0 到 100)来设置该视图的长度。重量将在适配器中动态改变。您可以在布局资源文件 (list_view_each_row.xml) 中设置的其他属性。

    另外,我相信您必须创建自己的自定义列表适配器(以便在列表应显示文本或进度时正确处理)。此自定义列表应扩展 BaseAdapter 并应覆盖强制方法。

    因此,在单击任何选项后,您可以更改适配器(您应该通知适配器用户单击了某个选项)。基于这个新信息,适配器可以隐藏所有的 TextViews 并且只显示有进度的 Views。

    以下是示例代码: 您可以在适配器中添加安全检查(空指针)。我使用了一个简单的数组。您可以更改为 ArrayList 并动态添加/删除项目。此外,您只能在“OnItemClickListener”内设置进度值。这只是一个例子。

    MainActivity

    public class MainActivity extends Activity {
    
        private MyCustomListAdapter adapter; 
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ((ListView) findViewById(R.id.list_view)).setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    // Force list view to populate its content again (now, with progress instead of text)
                    adapter.setIfUserAlreadyClickedOption(true);
                    adapter.notifyDataSetChanged();
                }
            });
    
            adapter = new MyCustomListAdapter();
    
            // Set click to false (user did not clicked yet)
            adapter.setIfUserAlreadyClickedOption(false);
    
            // Set text and progress
            adapter.setOptions(new String []{"Option1", "Option2", "Option3"});
            adapter.setProgressBarValues(new float [] {50,75,25});
            ((ListView)findViewById(R.id.list_view)).setAdapter(adapter);
        }
    }
    

    MyCustomListAdapter.java

    public class MyCustomListAdapter extends BaseAdapter {
    
        private boolean userAlreadyCliced;
        private String [] stringTexts;
        private float [] progressBarValues;
    
        public MyCustomListAdapter() {
            userAlreadyCliced = false;
        }
    
        public void setIfUserAlreadyClickedOption(boolean clicked) {
            userAlreadyCliced = clicked;
        }
    
        public void setOptions(String  [] text) {
            stringTexts = text;
        }
    
        public void setProgressBarValues(float [] values) {
            progressBarValues = values;
        }
    
        @Override
        public int getCount() {
            return stringTexts.length;
        }
    
        @Override
        public Object getItem(int position) {
            return stringTexts[position];
        }
    
        @Override
        public long getItemId(int position) {
            return 0;
        }
    
        @Override
        public View getView(int position, View view, ViewGroup parentViewGroup) {
            if(view == null) {
                view = LayoutInflater.from(parentViewGroup.getContext()).inflate(R.layout.list_view_each_row, parentViewGroup, false);
            }
    
            if(userAlreadyCliced) {
                // Hide Text
                view.findViewById(R.id.progress_view).setVisibility(View.VISIBLE);
    
                // Show Text and set progress
                ((LinearLayout.LayoutParams) view.findViewById(R.id.progress_view).getLayoutParams()).weight = progressBarValues[position];
                view.findViewById(R.id.text_view).setVisibility(View.GONE);
            } else {
                // Hide Progress
                view.findViewById(R.id.progress_view).setVisibility(View.GONE);
    
                // Show and set text
                view.findViewById(R.id.text_view).setVisibility(View.VISIBLE);
                ((TextView)view.findViewById(R.id.text_view)).setText(stringTexts[position]);
            }       
            return view;
        }
    }
    

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
    
    </LinearLayout>
    

    list_view_each_row.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="100" >
    
       <View
           android:id="@+id/progress_view"
           android:background="#0000FF"
           android:layout_width="0dp"
           android:layout_height="40dp"/>
    
        <TextView
            android:id="@+id/text_view"
            android:visibility="visible"
            android:layout_width="match_parent"
            android:layout_height="40dp" />
    
    </LinearLayout>
    

    【讨论】:

    • @Mr_Hmp 你为什么不使用 ClipDrawable 并将其设置为项目的背景,而不是那样?
    • pskink 我直到现在才知道它,但现在我认为这是一个非常简单易行的解决方案。谢谢
    【解决方案3】:

    您将需要一个彩色组件来显示您的效果。

    您可以设置一个带有背景颜色的视图并将其添加到其他视图下。

    或者,您可以覆盖您的视图并通过 onDraw(Canvas) 绘制颜色槽。

    【讨论】:

      【解决方案4】:

      假设您要放置一个需要左对齐的两个视图,其宽度应为百分比

      你可以使用 "android:layout_weight" 让一个更大一个更小

      参考这个Linear Layout and weight in Android

      参考这个Percentage width in a RelativeLayout

      【讨论】:

        猜你喜欢
        • 2019-10-07
        • 2014-09-28
        • 2021-09-19
        • 2017-01-23
        • 1970-01-01
        • 1970-01-01
        • 2022-10-13
        • 1970-01-01
        • 2013-09-16
        相关资源
        最近更新 更多