关于安卓ListView的item中添加自定义组件无法显示问题

问题

写了个数独小游戏,现在想在显示列表中能够预览题目的内容,写了个自定义的组件,但是添加进去之后,显示不完全。不报错,在初始化列表的时候显示所有的列表中的自定义组件的对象都是同一个,然后在添加显示的数据信息之后每个列表的对象又不一样了。

在这里插入图片描述
下面这两次输出全部都是在一次添加数据的时候出现的(这个已经找到原因了,放在文章最后)
在这里插入图片描述

布局

<?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"
    android:background="@color/colorGray81">

    <com.modev.sudoku.views.CoverImage
        android:id="@+id/home_item_cover"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_margin="10dp"/>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="80dp"
        android:gravity="center"
        android:background="@color/colorGray81">

        <TextView
            android:id="@+id/home_item_tv_level"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:textColor="@color/black"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/home_item_tv_diff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="7dp"
            android:textColor="@color/black"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/home_item_tv_status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="7dp"
            android:textColor="@color/black"
            android:textSize="18sp" />
    </LinearLayout>

</LinearLayout >

适配器

package com.modev.sudoku.adapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.modev.sudoku.R;
import com.modev.sudoku.modile.Problem;
import com.modev.sudoku.views.CoverImage;

import java.util.List;

public class HomeListViewAdapter extends ArrayAdapter<Problem> {
    private int resource;

    public HomeListViewAdapter(@NonNull Context context, int resource, @NonNull List<Problem> objects) {
        super(context, resource, objects);
        this.resource = resource;

    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Problem problem = getItem(position);
        View view;
        ViewHolder viewHolder;

        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resource, parent, false);
            viewHolder = new ViewHolder();


            viewHolder.coverImage = view.findViewById(R.id.home_item_cover);
            viewHolder.level = view.findViewById(R.id.home_item_tv_level);
            viewHolder.diff = view.findViewById(R.id.home_item_tv_diff);
            viewHolder.status = view.findViewById(R.id.home_item_tv_status);
            view.setTag(viewHolder);
        }else {
            view = convertView;
            viewHolder = (ViewHolder)view.getTag();
        }

        Log.d("测试", "coverImage:" + viewHolder.coverImage + "\t ProblemId:" + problem.getId());

        viewHolder.coverImage.setProblem(problem);

        viewHolder.level.setText("第"+(problem.getId())+"题");
        viewHolder.diff.setText("难度:"+problem.getDiff());
        if (problem.getStatus() == -1) {
            viewHolder.status.setText("状态:未尝试");
        }else if (problem.getStatus() == 0) {
            viewHolder.status.setText("状态:未完成");
        }else {
            viewHolder.status.setText("状态:已完成");
        }
        return view;
    }

    public void setProblemsList(List<Problem> problems) {
        super.clear();
        super.addAll(problems);

//        super.notifyDataSetChanged();
    }
    class ViewHolder{
        CoverImage coverImage;
//        ImageView cover;
        TextView level;
        TextView diff;
        TextView status;
    }
}

自定义视图组件

package com.modev.sudoku.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

import com.modev.sudoku.modile.Problem;

public class CoverImage extends View {
    private int height;
    private int width;
    private float sideLenght;
    private Problem problem;

    public CoverImage(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        height = getMeasuredWidth();
        width = getMeasuredWidth();
        sideLenght = width / 9F;
        setMeasuredDimension(width,height);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paintPanel(canvas);

        if (problem != null) {
            paintNumbers(canvas);
        }
    }

    private void paintPanel(Canvas canvas) {
        //浅色线条
        Paint grayPaint = new Paint();
        grayPaint.setColor(Color.GRAY);

        //深色线条
        Paint blackPaint = new Paint();
        blackPaint.setStrokeWidth(5);
        blackPaint.setColor(Color.BLACK);

        //绘制浅色线条
        for (int i = 0; i <= 9; i++) {
            canvas.drawLine(i*width/9F, 0F, i*width/9F, height, grayPaint);
            canvas.drawLine(0F, i*height/9F, width, i*height/9F, grayPaint);

        }

        //绘制四条深色线条
        canvas.drawLine(width/3F, 0f, width/3F, height, blackPaint);
        canvas.drawLine(2F*width/3F, 0f, 2F*width/3F, height, blackPaint);
        canvas.drawLine(0, height/3F, width, height/3F, blackPaint);
        canvas.drawLine(0, 2F*height/3F, width, 2F*height/3F, blackPaint);
    }

    private void paintNumbers(Canvas canvas) {

        //数组
        int[][] problemArr = problem.getDefaultProblem();

        //绘制数字的黑色颜色,设置字体大小,居中,颜色
        Paint blackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        blackPaint.setColor(0xFF666666);
        blackPaint.setTextSize(18);
        blackPaint.setTextAlign(Paint.Align.CENTER);

        //灰色蒙版的颜色,设置颜色,透明度
        Paint grayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        grayPaint.setColor(Color.GRAY);
        grayPaint.setAlpha(55);

        //遍历数组,然后画东西
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (problemArr[i][j] != 0) {
                    canvas.drawText(String.valueOf(problemArr[i][j]), j*sideLenght+sideLenght/2, i*sideLenght+3*sideLenght/4, blackPaint);
                    canvas.drawRect(j*sideLenght, i*sideLenght, j*sideLenght+sideLenght, i*sideLenght+sideLenght,grayPaint );
                }
            }
        }
    }

    public void setProblem(Problem problem) {
        this.problem = problem;

        invalidate();
    }

}

在界面中添加适配器的代码

    private void setMethod() {
        adapter = new HomeListViewAdapter(getApplicationContext(), R.layout.home_item, new ArrayList<Problem>());
        problemsLv.setAdapter(adapter);
   }

	//因为服务在一开始并不会创建,没有数据,之后在服务类中添加数据,这个是在服务器类中的
	//在服务初始化后添加数据
	adapter.setProblemsList(getProblems());

解决方案

不显示的原因:
重写OnMeasure()调用父类的方法的时候,这个应该放在第一行,然后就ok了,咋回事咱也不知道,反正就这么解决了。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

关于会出现列表项两次初始化的原因已经找到了,看下面这篇文章就行了
android ListView 在初始化时多次调用getView()原因分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值