Android 如果没有从服务器返回图像,则在imageview中显示默认图像

Android 如果没有从服务器返回图像,则在imageview中显示默认图像,android,Android,目标 当没有从服务器下载映像时,显示默认映像 问题 我有一个带有图像视图的列表视图(还有一些文本框,但这并不重要)。 我的imageview为学生下载图像,但当学生没有图像时,我尝试显示默认图像。 我已经尝试了两件我认为应该有效的事情,设置一个默认图像,或者下面的代码。 这段代码取自一个活动文件,我在其中将数据库列中的值写入变量(仅显示img以保持简单性) 然而,我在imgv=(ImageView)findviewbyd(R.id.ivImage)上得到一个空引用

目标

当没有从服务器下载映像时,显示默认映像

问题

我有一个带有图像视图的列表视图(还有一些文本框,但这并不重要)。 我的imageview为学生下载图像,但当学生没有图像时,我尝试显示默认图像。 我已经尝试了两件我认为应该有效的事情,设置一个默认图像,或者下面的代码。 这段代码取自一个活动文件,我在其中将数据库列中的值写入变量(仅显示img以保持简单性)

然而,我在
imgv=(ImageView)findviewbyd(R.id.ivImage)上得到一个空引用
对于更多的上下文,上面的代码是一个调用listview.xml的活动,然后调用row.xml。有问题的imageview位于row.xml文件中

ROW.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="4dp"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <ImageView
            android:id="@+id/ivImage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:src="@drawable/empty_head" /> //default image here

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/tvFirstName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/primary"
                android:textAppearance="?android:attr/textAppearanceLarge" />
            </LinearLayout>
    </LinearLayout>
</LinearLayout>

//这里的默认图像
调用行的列表

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="450dp"
        tools:listitem="@layout/row" >
    </ListView>
</LinearLayout>

适配器:

public class DriverAdapter extends ArrayAdapter<Drivers> {

    ArrayList<Drivers> ArrayListDrivers;
    int Resource;
    Context context;
    LayoutInflater vi;

    public DriverAdapter(Context context, int resource, ArrayList<Drivers> objects) {
        super(context, resource, objects);

        ArrayListDrivers = objects;
        Resource = resource;
        this.context = context;

        vi = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        if (convertView == null) {
            convertView = vi.inflate(Resource, null);
            holder = new ViewHolder();

            holder.imageview = (ImageView) convertView.findViewById(R.id.ivImage);
            holder.tvName = (TextView) convertView.findViewById(R.id.tvFirstName);
            holder.tvDescription = (TextView) convertView.findViewById(R.id.tvLastName);
            holder.tvClientid = (TextView) convertView.findViewById(R.id.tvid);
            holder.tvExpires = (TextView) convertView.findViewById(R.id.tv_expdate);

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.imageview.setImageResource(R.drawable.ic_launcher);
            new DownloadImageTask(holder.imageview).execute(ArrayListDrivers.get(position).getImage());


        Glide.with(holder.imageview.getContext())
                .load(new DownloadImageTask(holder.imageview).execute(ArrayListDrivers.get(position).getImage())        )
                .centerCrop()
                .placeholder(R.drawable.ic_launcher)
                .crossFade()
                .into(holder.imageview);


        holder.tvName.setText(ArrayListDrivers.get(position).getFirstname());
        holder.tvDescription.setText(ArrayListDrivers.get(position).getLastname());
        holder.tvClientid.setText(ArrayListDrivers.get(position).getClient_id());
        holder.tvExpires.setText("Expiry Date:"+ArrayListDrivers.get(position).getExpires());



        return convertView;


    }

    static class ViewHolder {
        public ImageView imageview;
        public TextView tvName;
        public TextView tvDescription;
        public TextView tvClientid;
        public TextView tvExpires;

    }


    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap cImg1 = null;


            try {

                byte[] decodedString = Base64.decode(urldisplay, Base64.DEFAULT);
                cImg1 = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);


            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return cImg1;


        }

        protected void onPostExecute(Bitmap result) {

            bmImage.setImageBitmap(result);


        }
    }
}
公共类DriverAdapter扩展了ArrayAdapter{
ArrayList ArrayList驱动程序;
智力资源;
语境;
拉平机vi;
public DriverAdapter(上下文、int资源、ArrayList对象){
超级(上下文、资源、对象);
ArrayListDrivers=对象;
资源=资源;
this.context=上下文;
vi=(LayoutFlater)上下文
.getSystemService(上下文布局\充气机\服务);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视窗座;
if(convertView==null){
convertView=vi.inflate(资源,空);
holder=新的ViewHolder();
holder.imageview=(imageview)convertView.findViewById(R.id.ivImage);
holder.tvName=(TextView)convertView.findViewById(R.id.tvFirstName);
holder.tvDescription=(TextView)convertView.findViewById(R.id.tvLastName);
holder.tvClientid=(TextView)convertView.findViewById(R.id.tvid);
holder.tvExpires=(TextView)convertView.findViewById(R.id.tv_expdate);
convertView.setTag(支架);
}否则{
holder=(ViewHolder)convertView.getTag();
}
holder.imageview.setImageResource(R.drawable.ic_启动器);
新下载的ImageTask(holder.imageview).execute(ArrayListDrivers.get(position.getImage());
Glide.with(holder.imageview.getContext())
.load(新下载的ImageTask(holder.imageview).execute(ArrayListDrivers.get(position.getImage()))
.centerCrop()
.占位符(R.drawable.ic_启动器)
.crossFade()
.插入(支架.图像视图);
holder.tvName.setText(ArrayListDrivers.get(position.getFirstname());
holder.tvDescription.setText(ArrayListDrivers.get(position.getLastname());
holder.tvClientid.setText(ArrayListDrivers.get(position.getClient_id());
holder.tveexpires.setText(“到期日期:+ArrayListDrivers.get(position.getExpires());
返回视图;
}
静态类视窗夹{
公共影像视图;
公共文本视图tvName;
公共文本视图描述;
公共文本视图tvClientid;
公共文本视图;
}
私有类DownloadImageTask扩展了AsyncTask{
图像视图bmImage;
公共下载ImageTask(ImageView bmImage){
this.bmImage=bmImage;
}
受保护位图doInBackground(字符串…URL){
字符串urldisplay=url[0];
位图cImg1=null;
试一试{
字节[]decodedString=Base64.decode(urldisplay,Base64.DEFAULT);
cImg1=BitmapFactory.decodeByteArray(decodedString,0,decodedString.length);
}捕获(例外e){
Log.e(“Error”,e.getMessage());
e、 printStackTrace();
}
返回cImg1;
}
受保护的void onPostExecute(位图结果){
bmImage.setImageBitmap(结果);
}
}
}
此方法在以下情况下有效- 在xml代码中设置默认图像,当学生没有图像时将显示该图像。 如果获得图像,请使用setImageResource(…)动态设置图像


当出现空引用错误时,请重新检查ImageView的id,如果这不能解决问题,请发布完整的活动代码。

有更好的方法,您可以使用一个图像加载库,如:

Android的图像加载和缓存库专注于平滑滚动

你只需要一行就可以做你想做的事

    Glide.with(myFragment)
    .load(url)
    .placeholder(R.drawable.loading_spinner)
    .into(myImageView);

它更简单、更干净。

Listview的适配器负责管理行的视图。 你的适配器是什么样子的?(在上调用listview.setAdapter(适配器)的对象)

在适配器内部,有一个方法调用getView,您需要重写并返回一个视图对象。您需要在此视图对象而不是活动上调用view.findviewbyId()

更新 试着去掉这些线

holder.imageview.setImageResource(R.drawable.ic_launcher);
        new DownloadImageTask(holder.imageview).execute(ArrayListDrivers.get(position).getImage());

你能解释一下调用Glide.with(Context.load)(object)的目的吗?谢谢

在您的
异步任务构造函数中
尝试如下初始化图像视图

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = inflater.inflate(R.layout.row, null, false);
ivImage= (ImageView ) convertView.findViewById(R.id.ivImage);

在这里
row.xml
声明ImageView。。。并确保ivImage是全局变量。。。现在ivImage不是空的。我查过了。。但是使用
adapter
类来管理
listview行更好…

我通过做一些非常简单的事情来解决这个问题。 在aync方法的后期执行中
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = inflater.inflate(R.layout.row, null, false);
ivImage= (ImageView ) convertView.findViewById(R.id.ivImage);
  if (result != null){
                bmImage.setImageBitmap(result);
            }
   implementation 'com.github.bumptech.glide:glide:4.11.0'
   implementation 'jp.wasabeef:glide-transformations:4.0.0'
  Glide.with(mActivity.getApplicationContext())
                            .load(EndPoints.ROWS_IMAGE_URL + ImageUrl)
                            .asBitmap()
                            .centerCrop()
                            .transform(new CropCircleTransformation(mActivity.getApplicationContext()))
                            .apply(new RequestOptions().
                            .placeholder(drawable)
                            .error(drawable)
                            .override(AppConstants.ROWS_IMAGE_SIZE, AppConstants.ROWS_IMAGE_SIZE))
                            .into(target);
   .placeholder(drawable)