android - 如何选择一个 ListView 行并突出显示它(几个 TextView)?

标签 android listview

我有一个 ListView其中每一行都有三个 TextView,显示有关名为 Medidor(Meter)的对象的信息。

我的问题是:如何在 onClick 事件发生时将整行标记为已选中?如果选中,我只需要使当前行的颜色变暗,否则恢复正常。

我考虑在包含对象的列表上使用 setOnItemClickListener(在我的 ArrayList<Medidor> medidores 上使用 Activity,但我不知道它与 Adapter 的确切关系,特别是与 getView 方法的关系使其发挥作用。

这是我的适配器的代码:

public class ListaMedidoresAdapter extends BaseAdapter {
    private ArrayList<Medidor> medidores;
    private Activity activity;
    private TextView codMedidor;
    private TextView nombreMedidor;
    private TextView obsLectMedidor;
    static Long cod_medidor_seleccionado = 0L;
    private static final Boolean COLORES_UBICS_ALTERN = false; //false para agrupar las ubicaciones en colores distintos para cada ubicación

    private static final String[] colores_tabla = {"#770077","#002222","#228822","#881133","#602000","#202020","#6432c8","#c8323e","#32c870","#32a9c8","#c8b632","#c84f32","#383332","#6a7c68","#72687c","#590346","#5652c4","#404c33","#4a13ef","#ef6013",
            "#724c12","#062307","#159fb5","#77797a","#107ea3","#a31010","#663c3c","#a00088","#383637","#662222","#224466","#5c748c","#8c875c","#5c8c80","#70962a","#3722f4","#a36758","#8e5518","#61188e","#af0150",
            "#214add","#697293","#4f5466","#02686d","#2d026d","#7b6899","#50ba5f","#e85e27","#a4ba01","#ff0026"};

    private static final String[] colores_altern = {"#2b7f4a","#7f2b30"};

    private String color_seleccionado_conjunto = "";

    private ArrayList<Integer> colores_seleccionados;
    private Integer color_selecc;

    private Context ctx;

    ListaMedidoresAdapter(Activity activity, ArrayList<Medidor> listaMedidores, Context ctx){
        super();
        this.activity = activity;
        this.medidores = listaMedidores;
        this.ctx = ctx;
        colores_seleccionados = new ArrayList<>();
        color_selecc = 0;
    }


    @Override
    public int getCount() {
        return medidores.size();
    }

    @Override
    public Medidor getItem(int i) {
        return medidores.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @SuppressLint("Range")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = activity.getLayoutInflater();
        if(convertView == null){
            convertView = inflater.inflate(R.layout.fila_medidor,null);
            codMedidor = convertView.findViewById(R.id.codigo_medidor);
            nombreMedidor = convertView.findViewById(R.id.nombre_medidor);
            obsLectMedidor = convertView.findViewById(R.id.estado_lects_medidor);
        }
        Medidor m = medidores.get(position);

        nombreMedidor.setText(m.getNombre());
        obsLectMedidor.setText(m.getLecturaStatus());
        obsLectMedidor.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);

        if(m.getCodigo_medidor() == null){ //Es cabecera de ubicación
            nombreMedidor.setTypeface(null, Typeface.BOLD);
            if(COLORES_UBICS_ALTERN){ //Seleccionar alternadamente entre dos colores
                codMedidor.setBackgroundColor(Color.parseColor(colores_altern[color_selecc]));
                nombreMedidor.setBackgroundColor(Color.parseColor(colores_altern[color_selecc]));
                obsLectMedidor.setBackgroundColor(Color.parseColor(colores_altern[color_selecc]));
                color_selecc = (color_selecc == 0) ? 1:0;
            } else { //Seleccionar un color al azar
                color_seleccionado_conjunto = seleccionarColor();
                codMedidor.setBackgroundColor(Color.parseColor(color_seleccionado_conjunto));
                nombreMedidor.setBackgroundColor(Color.parseColor(color_seleccionado_conjunto));
                obsLectMedidor.setBackgroundColor(Color.parseColor(color_seleccionado_conjunto));
            }
        } else { //Es un medidor
            if(COLORES_UBICS_ALTERN){ //Seleccionar alternadamente entre dos colores
                codMedidor.setBackgroundColor(Color.parseColor(colores_altern[color_selecc]));
                nombreMedidor.setBackgroundColor(Color.parseColor(colores_altern[color_selecc]));
                color_selecc = (color_selecc == 0) ? 1:0;
            } else { //Seleccionar un color al azar
                codMedidor.setBackgroundColor(Color.parseColor(color_seleccionado_conjunto));
                nombreMedidor.setBackgroundColor(Color.parseColor(color_seleccionado_conjunto));
            }
            if(m.getCodigo_medidor() != null){
                String codMedidorAbreviado = m.getCodigo_medidor().split(" ")[1] + m.getCodigo_medidor().split(" ")[2];
                codMedidor.setText(codMedidorAbreviado);
            }
            switch (m.getLecturaStatus()){
                case "S/L":
                    obsLectMedidor.setBackgroundColor(Color.RED);
                    break;
                case "OBS":
                    obsLectMedidor.setBackgroundColor(Color.YELLOW);
                    break;
                case "OK":
                    obsLectMedidor.setBackgroundColor(Color.GREEN);
                    break;
                default:
                    obsLectMedidor.setBackgroundColor(Color.GRAY);
                    break;
            }
        }
        TextView ubicacionMedidor = convertView.findViewById(R.id.ubicacionMedidorSelecc);
        return convertView;
    }

    private String seleccionarColor(){
        Integer ran_num=0;
        Random ran = new Random();
        Boolean new_ran = false;
        while(new_ran == false){
            ran_num = ran.nextInt(50);
            Log.i("RAN",ran_num.toString());
            Boolean yaSeleccionado = false;
            if(colores_seleccionados.size() < 50) {
                for (int i = 0; i < colores_seleccionados.size(); i++) {
                    if (colores_seleccionados.get(i) == ran_num) {
                        Log.i("COLORS", "Color seleccionado ya existe en posición " + ran_num.toString());
                        yaSeleccionado = true;
                        break;
                    }
                }
                new_ran = !yaSeleccionado;
            } else { //Ya fueron todos los colores disponibles seleccionados, ahora sólo debe asegurarse que no elija el mismo color que la ubicación anterior
                if(ran_num != colores_seleccionados.get(colores_seleccionados.size()-1)){
                    new_ran = true;
                }
            }
        }
        colores_seleccionados.add(ran_num);
        Log.i("RAN_COLOR",colores_tabla[ran_num]);
        return colores_tabla[ran_num];
    }
}

颜色相关的东西为“行”选择背景颜色(通过 TextView 对象),以便在视觉上区分具有不同属性值(位置)的 Medidor 对象。

这是 fila_medidor.xml(三个 TextView 对象定义在一个“行”中):

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

    <TextView
        android:id="@+id/codigo_medidor"
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="0.15"
        android:layout_marginBottom="0dp"
        android:layout_marginTop="0dp"
        android:textSize="14sp" />

    <TextView
        android:id="@+id/nombre_medidor"
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="0.7"
        android:layout_marginBottom="0dp"
        android:layout_marginTop="0dp"
        android:textSize="14sp"/>

    <TextView
        android:id="@+id/estado_lects_medidor"
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="0.15"
        android:layout_marginBottom="0dp"
        android:layout_marginTop="0dp"
        android:textSize="14sp"/>
</LinearLayout>

在我的 Activity 中,我有以下与 ListView - Adapter 相关的行:

ListaMedidoresAdapter adapter = new ListaMedidoresAdapter(this,arregloMedidores,this);
listaMedidores.setAdapter(adapter);

哪里arregloMedidores类型为 ArrayList<Medidor> .

为什么我没有选择 TableLayout ?因为在我看来,很难附加到像数组这样的动态数据源,而且它会消耗更多资源,因为它将所有 View 保存在内存中,这对于 1000 个条目可能是个问题。

提前谢谢你。

最佳答案

尝试添加行: android:background="@drawable/medidor_background" 到你的 fila_medidor.xml LinearLayout

然后在 drawable 文件夹中创建一个新的 medidor_background.xml 文件,内容为:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="true"
        >
        <shape>
            <solid
                android:color="#000000"
                />
        </shape>
    </item>

    <item>
        <shape>
            <solid
                android:color="#FFFFFF"
                />
        </shape>
    </item>
</selector>

关于android - 如何选择一个 ListView 行并突出显示它(几个 TextView)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47780761/

相关文章:

xaml - ViewCell 未正确对齐并剪切部分内容 - Xamarin Forms

android - 如何在 Android 的 ListView 内的 imageview 中设置图像?

java - 带有包含复选框的自定义适配器的 ListView

android - 优化 NEON 装配功能

java - 一个 Button 的 2 个 OnClick 监听器无法解析 OnClickListener

android - 有没有更好的方法从适配器获取对父 RecyclerView 的引用?

java - 将 ListView 内的产品价格总和计算为字符串

android - 如何使列表项变灰?

java - 从字符串中获取枚举索引?

android - 完成在堆栈中留下 Activity