6

截屏

在上图中,有一个列表视图,其中包含用户可以下载的项目列表。下载按钮这是告诉用户他可以下载文件的图像。下载完成后,图片将变为下载完成按钮. 我的问题是当我下载文件时,状态图像(表示下载已完成)会更改为另一行,相反,它应该更改为我选择的行。目前,如果我下载列表中的第一个文件,图像会更改为列表中的第 4 或第 5 项。此外,当我尝试从列表中下载任何其他文件时。它会打开最后下载的文件(这是应用程序的功能,如果文件已经下载,则在 pdf 阅读器中打开它),即,如果我下载列表中的第一个文件然后转到第二个项目,那么而不是下载第二个文件,它会打开最后下载的文件。此外,如果我滚动列表视图,列表中其他项目的下载状态也会更改。下面是我的适配器代码:

public class DownloadListAdapter extends BaseAdapter {
Context ctx;
public ArrayList<DownloadListDao> mDownloadList;
String readMoreLink;
public static final String TAG = "DownloadListAdapter";
ProgressDialog mProgressDialog;
private boolean isSDCardPresent;
File tieDir;
int downloadState[];

public DownloadListAdapter(Context ctx,
        ArrayList<DownloadListDao> mDownloadList) {
    this.ctx = ctx;
    this.mDownloadList = mDownloadList;
    downloadState = new int [mDownloadList.size()];
    for(int i = 0; i < mDownloadList.size(); i++) {
        downloadState[i] = 0;
    }
    tieDir = new File(Environment.getExternalStorageDirectory().toString()
            + "/tie");
}// Constructor

public int getCount() {
    return this.mDownloadList.size();
}// getCount

public Object getItem(int position) {
    return this.mDownloadList.get(position);
}// getItem

public long getItemId(int position) {
    return 0;
}// getItemId

static class ViewHolder {
    TextView txtTitle, txtTheme, txtDate;
    ImageView imgDownload;
}// ViewHolder

ViewHolder holder;

public View getView(final int position, View convertView, ViewGroup parent) {
    final String url = mDownloadList.get(position).getUrl();
    if (convertView == null) {
        convertView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.downlist_adapter, null);
        holder = new ViewHolder();

        holder.txtTitle = (TextView) convertView
                .findViewById(R.id.txtTitle);
        holder.txtTheme = (TextView) convertView
                .findViewById(R.id.txtTheme);
        holder.txtDate = (TextView) convertView.findViewById(R.id.txtDate);
        holder.imgDownload = (ImageView) convertView
                .findViewById(R.id.imgDload);

        holder.imgDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File mediaFile = null;
                if (url != null && !url.equals("null") && !url.equals("")) {
                    String fileName = url.toString().substring(
                            url.toString().lastIndexOf("/") + 1,
                            url.toString().length());
                    mediaFile = new File(tieDir, fileName);
                }
                processFile(mediaFile, url, position);
                int pos = (Integer)v.getTag();
                downloadState[pos] = 1;
            }
        });
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    if (mDownloadList != null && mDownloadList.size() > 0) {
        if (mDownloadList.get(position).getTitle() != null
                && !mDownloadList.get(position).getTitle().equals("null")
                && !mDownloadList.get(position).getTitle().equals("")) {
            holder.txtTitle.setText(mDownloadList.get(position).getTitle());
        }

        if (mDownloadList.get(position).getTheme() != null
                && !mDownloadList.get(position).getTheme().equals("null")
                && !mDownloadList.get(position).getTheme().equals("")) {
            holder.txtTheme.setText(mDownloadList.get(position).getTheme());
        }

        if (mDownloadList.get(position).getDate() != null
                && !mDownloadList.get(position).getDate().equals("null")
                && !mDownloadList.get(position).getDate().equals("")) {
            holder.txtDate.setText(mDownloadList.get(position).getDate());
        }

        if (downloadState[position] == 1) {
            holder.imgDownload.setImageDrawable(ctx.getResources()
                    .getDrawable(R.drawable.ic_dloaded));
        } else {
            holder.imgDownload.setImageDrawable(ctx.getResources()
                    .getDrawable(R.drawable.ic_dload));
        }
    }
    holder.imgDownload.setTag(position);
    return convertView;
}// getView

protected void downloadFile(String url, int position, String fileName) {

    Log.v(TAG, "Preparing to download");
    mProgressDialog = new ProgressDialog(ctx);
    mProgressDialog.setMessage("Dowloading...");
    mProgressDialog.setIndeterminate(false);
    mProgressDialog.setMax(100);
    mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

    isSDCardPresent = Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED);
    if (!isSDCardPresent) {
        noSDCardAlert(ctx);
    } else {
        if ((tieDir.exists()) && (tieDir != null)) {
            if (NetworkConnection.isOnline(ctx)) {
                if (tieDir.isDirectory()) {
                    Log.v(TAG, "if tie dir URL:::" + url);
                    new DownloadAudioAsync(ctx, position, fileName).execute(url);
                }
            } else {
                ((DownloadListActivity) ctx)
                        .OpenNetErrDialog("Please check your internet connection...");
            }
        } else {
            boolean isDirectoryCreated = tieDir.mkdirs();
            if (isDirectoryCreated) {
                Log.v(TAG, "if tie not dir URL:::" + url);
                if (NetworkConnection.isOnline(ctx)) {
                    new DownloadAudioAsync(ctx, position, fileName).execute(url);
                } else {
                    ((DownloadListActivity) ctx)
                            .OpenWiFiDialog("Please check your internet connection...");
                }
            }
        }
    }
}

private void noSDCardAlert(Context ctx) {
    AlertDialog.Builder ad = new AlertDialog.Builder(ctx);
    ad.setMessage("No sd card present..");
    ad.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });

    if (!((DownloadDetail) ctx).isFinishing()) {
        ad.show();
    }
}

public void OpenDialog(String messageID) {

    final Dialog dialog = new Dialog(ctx,
            android.R.style.Theme_Translucent_NoTitleBar);
    dialog.setContentView(R.layout.dialog_base);
    dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
    dialog.setCancelable(false);

    TextView alertMessage = (TextView) dialog.findViewById(R.id.txtMessage);
    Button btnOK = (Button) dialog.findViewById(R.id.btnOk);
    btnOK.setText("Show");
    alertMessage.setText(messageID);
    dialog.show();
    btnOK.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            dialog.dismiss();
        }
    });
}

protected void showPdf(File mediaFile) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(mediaFile), "application/pdf");
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    ctx.startActivity(intent);
}

public class DownloadAudioAsync extends AsyncTask<String, String, String> {
    Context ctx;
    int pos;
    private ProgressDialog pd;
    String fileName;

    public DownloadAudioAsync(Context ctx, int pos, String fileName) {
        this.ctx = ctx;
        this.pos = pos;
        this.fileName = fileName;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.v(TAG, "inside on pre execute");
        pd = new ProgressDialog(ctx);
        pd.setMessage("Downloading...\nPlease wait..");
        pd.show();
    }

    @Override
    protected String doInBackground(String... aurl) {
        int count;

        try {
            Log.v(TAG,
                    "inside do in background with url::"
                            + aurl[0].toString());
            aurl[0] = aurl[0].replaceAll(" ", "%20");
            URL url = new URL(aurl[0]);

            URLConnection conexion = url.openConnection();
            conexion.connect();

            int lenghtOfFile = conexion.getContentLength();

            fileName = URLDecoder.decode(fileName, "UTF-8");
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(tieDir + "/"
                    + fileName);

            byte data[] = new byte[1024];

            long total = 0;

            while ((count = input.read(data)) != -1) {
                total += count;

                publishProgress("" + (int) ((total * 100) / lenghtOfFile));
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {
        }
        return null;
    }

    @Override
    protected void onPostExecute(String unused) {
        if (!((DownloadListActivity) ctx).isFinishing()) {
            pd.dismiss();
            updateView(pos);
        }
    }

    private void updateView(int pos) {
        View v = ((DownloadListActivity) ctx).menuListView.getChildAt(pos
                - ((DownloadListActivity) ctx).menuListView
                        .getFirstVisiblePosition());
        ImageView imgDloadBtn = (ImageView) v.findViewById(R.id.imgDload);
        imgDloadBtn.setImageDrawable(ctx.getResources().getDrawable(
                R.drawable.ic_dloaded));
        notifyDataSetChanged();
    }
}

private void processFile(File mediaFile, String url, int pos) {
    if (url != null && !url.equals("null") && !url.equals("")) {
        if (mediaFile != null) {
            Log.v(TAG, "in processFile FileName " + mediaFile.getName());
            Log.v(TAG, "in processFile Position " + pos);
            if(!mediaFile.exists()) {
                Log.v(TAG, "in processFile Media file doesn't exists");
                downloadFile(url, pos, mediaFile.getName());
            } else {
                Log.v(TAG, "in processFile Media file exists");
                try {
                    showPdf(mediaFile);
                } catch (ActivityNotFoundException anfe) {
                    OpenDialog("PDF Reader is not installed on your device.");
                }
            }
        }
    }
}
}// DownloadAdapter

我已经阅读了这篇文章以回收视图(感谢Knickedi的深入解释)。但是,我无法弄清楚实际问题在哪里。

4

1 回答 1

5

每当您滚动视图时都会重新创建方法的问题getview,以处理您必须使用的确切位置setTag & getTag,请查看以下几个 stackvoerflow 答案以了解setTag & getTag

使用 ArrayAdapter 的 ListView 中的按钮

从android中的自定义列表中获取单选按钮值

甚至将下载的状态存储到booleanarray 如下状态:

int boxState[];

在适配器构造函数中,最初设置为零:

for (int i = 0; i < getData.size(); i++) {
    boxState[i] = 0;

    }

在适配器 getview 方法中:

holder.imgDownload.setTag(position);

现在您单击下载按钮将值设置为 1(在按钮的 onclick 内):

pos = (Integer) v.getTag();
boxState[pos]=1;

最后,当您将视图检查条件滚动到以下方式时(将以下代码放入 getview 方法中):

if (boxState[position] == 0) {
            holder.imgDownload.setImageDrawable(ctx.getResources()
                    .getDrawable(R.drawable.ic_dloaded)); //which aren't downloaded
        } else {
             holder.imgDownload.setImageDrawable(ctx.getResources()
                    .getDrawable(R.drawable.ic_dload)); // which are downloaded.
        }
于 2013-04-12T07:38:30.080 回答