2

私はAndroidプログラミングの初心者です。今では有線のものに出会い、listActivityを作成しました。リスト項目のレイアウトは次のようになります:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:paddingBottom="10dp"
    android:paddingTop="15dp" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/transparent" >

        <ImageView
            android:id="@+id/offlineItemIcon"
            android:layout_width="44dp"
            android:layout_height="44dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginTop="5dp"
            android:scaleType="fitXY"
            android:src="@drawable/user_avatar" />

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

            <TextView
                android:id="@+id/offlineItemTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingTop="5dp"
                android:text="卷001 2012-08-23 3.0M"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@color/lightdark"
                android:textSize="18sp" />

            <ProgressBar
                android:id="@+id/offlineLoadingbar"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="fill_parent"
                android:layout_height="5dp"
                android:layout_marginRight="20dp"
                android:layout_marginTop="15dp"
                android:max="100"
                android:progress="10" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center" >

            <Button
                android:id="@+id/buttonOfflineItemDownload"
                android:layout_width="60dp"
                android:layout_height="44dp"
                android:background="@drawable/xml_button_loadmore"
                android:text="download"
                android:textColor="@color/lightwhite"
                android:textSize="18sp" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:background="@color/commentDate" >
    </LinearLayout>

</LinearLayout>

このレイアウトのコンテンツをラップするクラスを作成しました。これは -

public class OfflineItemView extends LinearLayout {

    Context _context = null;

    public Button buttonDownload = null;
    public ProgressBar loadingProgress = null;
    public TextView title = null;
    public ImageView icon = null;

    public String url = null;
    public String filename = null;

    public OfflineItemView(Context context) {
        super(context);
        _context = context;
        init();
    }

    public OfflineItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        _context = context;
        init();
    }

    protected void init() {
        LayoutInflater inflater = (LayoutInflater) _context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.module_offline_item, this);

        buttonDownload = (Button) findViewById(R.id.buttonOfflineItemDownload);
        buttonDownload.setTag("download");

        loadingProgress = (ProgressBar) findViewById(R.id.offlineLoadingbar);
        loadingProgress.setMax(100);
        loadingProgress.setProgress(0);

        title = (TextView) findViewById(R.id.offlineItemTitle);
        icon = (ImageView) findViewById(R.id.offlineItemIcon);
    }

    public void setTitle(String message) {
        if (message != null) {
            title.setText(message);
        } else {
            title.setText("");
        }
    }

    public void setImageBitmap(Bitmap bitmap) {

        if (bitmap != null) {
            icon.setImageBitmap(bitmap);
        }
    }

    public void setListener(View.OnClickListener listener) {
        this.buttonDownload.setOnClickListener(listener);
    }

    public void setProgress (int i)
    {
        android.util.Log.v ("item", i + "");
        loadingProgress.setProgress(i);
        android.util.Log.v ("item", "current : " + loadingProgress.getProgress());
    }

}

リストはかなりうまく機能し、すべてのアイテムを問題なく表示します。リストアイテムのスクリーンショットは-

ここに画像の説明を入力

ユーザーがボタンをクリックすると、AsyncTask クラスが呼び出されてファイルがダウンロードされ、アイテムの進行状況が表示されます。

public void downloadOffline(String url, String path,
        OfflineItemView progress) {

    DownloadOfflineAsync downloader = new DownloadOfflineAsync(progress);
    downloader.execute(url, path);
}

class DownloadOfflineAsync extends AsyncTask<String, String, String> {

    private final WeakReference<OfflineItemView> progressbarReference;

    public DownloadOfflineAsync(OfflineItemView progress) {
        progressbarReference = new WeakReference<OfflineItemView>(progress);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

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

        try {

            URL url = new URL(aurl[0]);
            URLConnection conexion = url.openConnection();
            conexion.connect();

            int lenghtOfFile = conexion.getContentLength();
            android.util.Log.v("downloadFile", "Lenght of file: "
                    + lenghtOfFile + ":" + aurl[1]);

            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(aurl[1]);

            try {
                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);
                }


            } finally {

                if (output != null) {
                    output.flush();
                    output.close();
                }

                if (input != null) {

                    input.close();
                }
            }
        } catch (Exception e) {

            e.printStackTrace();

        }
        return null;

    }

    protected void onProgressUpdate(String... progress) {
        if (progressbarReference != null) {
            OfflineItemView p = progressbarReference.get();

            //android.util.Log.v ("offline.download", progress[0]);
            p.setProgress(Integer.parseInt(progress[0]));
        }
    }

    @Override
    protected void onPostExecute(String unused) {

        OfflineItemView p = null;

        if (progressbarReference != null) {
            p = progressbarReference.get();
            p.buttonDownload.setTag("browser");
            p.buttonDownload.setText("browse");
            p.requestLayout();
        }

    }
}

ファイルがダウンロードされ、進行状況が onProgressUpdate に通知され、アイテム クラスの読み込み進行状況バーも正常に機能し、進行状況が正しく設定されています (logcat に出力するため、すべて正しい)。ただし、問題は進行状況バーはインジケーターを更新しないため、進行状況が 0 から 100 に更新されても、進行状況バーは UI に進行状況を表示するために何も変更しないため、アドバイスをいただける方は大歓迎です..

PS:

ダウンロード機能を getView() に移動したところ、うまく機能しているようで、プログレスバーは更新されていますが、ボタンのイベントハンドラーが機能していないため、リストビューの問題のようですが、この問題を解決するにはどうすればよいですか?

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

        rowView = new OfflineItemView(_context);
        JSONObject item = getItem(position);

        try {
            if (item != null) {
                String t = item.getString(Offline.TAG_NAME) + " "
                        + item.getString(Offline.TAG_DATE) + " "
                        + item.getString(Offline.TAG_SIZE);

                rowView.setTitle(t);

                if (listener == null) {
                    listener = new ItemButtonOnClickListener();
                }

                if (item.optBoolean("dir_exists")) {
                    rowView.buttonDownload.setText("browse");
                    rowView.buttonDownload.setTag("browser");
                }

                rowView.setListener(listener);
                rowView.url = item.getString(Offline.TAG_URL);
                rowView.filename = item.getString(Offline.TAG_FILENAME);

                String imageUrl = item.optString(Offline.TAG_ICON);

                if (imageUrl == null || imageUrl.trim().equals("")) {

                } else {

                    String name = item.optString(Offline.TAG_UNZIP_NAME) + "o";
                    if (name != null) {
                        if (DiskCache.getInstance().fileExists("user_" + name,
                                "user")) {
                            android.util.Log.v("offline", name + ":exists");
                            Bitmap bitmap = DiskCache.getInstance().get(
                                    "user_" + name, "user");
                            if (bitmap != null) {
                                rowView.setImageBitmap(bitmap);
                            }
                        } else {

                            // FileDownloader.getInstance().download(imageUrl,
                            // image, name);
                        }

                    }
                }


            }
        }

        catch (Exception e) {
            e.printStackTrace();
        }

        return rowView;

    }
4

1 に答える 1

0

あなたはこれに一種の奇妙な方法でアプローチしています。Android は初めてだとおっしゃいましたが、上記のコメント スレッドからは、現在の壊れた状態がどのようなものかわかりません。ただし、ListViewベスト プラクティスに従っておらず、リストを下にスクロールすると奇妙な問題が発生する可能性があることはわかります。

与えられたパラメーターを使用する必要がありconvertViewます。 convertViewは null か、View以前に から返されgetViewた です。OfflineItemViewsのみを返すので、convertView != nullそれが のインスタンスになる場合はOfflineItemView、これを再利用して、新しいアイテムが表示されるたびに描画時に完全に新しいものを作成するオーバーヘッドを回避できます。

基本的:

View rowView;
if(convertView == null){
     rowView = convertView;
} else {
     rowView = new OfflineItemView(item);
}

次のようなロジックには注意してください。次にビューを再利用するときに、最後にビューを占有していたアイテムのタグがまだ残っているからです。

            if (item.optBoolean("dir_exists")) {
                rowView.buttonDownload.setText("browse");
                rowView.buttonDownload.setTag("browser");
            }

IE では、 falseであるイベントでタグを言って無効にするelse句が必要になる場合があります。rowView.buttonDownload.setText("");dir_exists

さらに、( にあるコメントアウトされたImageDownloaderコードのようなものを使用するつもりであると仮定するとgetView) 画像が画像キャッシュに存在しない場合、画像のgetView前に が複数回呼び出されると、同じ画像の複数のダウンロードが発生する可能性があります。実際にダウンロードされます。

質問を編集して、現在何が壊れているかを正確に明確にすることができれば、この回答を改良してさらに支援することができます。

于 2012-08-27T14:37:47.080 に答える