0

複数のファイルのダウンロードを表示するビューを実行しようとしています。ProgressDialogは、単一ファイルのダウンロード情報を表示するのに最適ですが、ListViewの要素として使用したり、複数のファイルを表示するように設定したりすることはできないと思います(またはできますか?)

だから私はこのようないくつかのガイドに示されているように独自のアダプターを実装し、それはうまくいきます、ダウンロードアイテム(名前のTextView +ファイルサイズに最大が設定されたProgressBar)を追加できますが、いくつかのリストアイテムでProgressBarを更新するにはどうすればよいですか?

これが悪い習慣である場合、複数のファイルのダウンロードの進行状況を表示するのに最適な方法はどれですか?

download_item.xml

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

<TextView
    android:id="@+id/download_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:textAppearance="?android:attr/textAppearanceMedium" />

<ProgressBar
    android:id="@+id/download_bar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@id/download_label" />
</RelativeLayout>

クラスをダウンロード

public class Download 
{
  public String name;
  public int size;

  public Download(String name, int size)
  {
    this.name = name;
    this.size = size;
  }
}

DownloadAdapterクラス

 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.ProgressBar;
 import android.widget.TextView;

 public class DownloadsAdapter extends ArrayAdapter<Download>
 {
   private int layoutResourceId;
   public DownloadsAdapter(Context context, int textViewResourceId)
   {
    super(context, textViewResourceId);
    this.layoutResourceId = textViewResourceId;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent)
   {
     DownloadHolder downloadHolder = null;
         if(convertView == null)
         {
            LayoutInflater inflater = (LayoutInflater) super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(layoutResourceId, parent, false);
            downloadHolder = new DownloadHolder();
            downloadHolder.progressBar = (ProgressBar)convertView.findViewById(R.id.download_bar);
            downloadHolder.label = (TextView)convertView.findViewById(R.id.download_label);
            Log.i("INFO", "HOLDER SET");
            convertView.setTag(downloadHolder);
         }
         else
         {
            downloadHolder = (DownloadHolder)convertView.getTag();
         }

        Download download = super.getItem(position);
        downloadHolder.label.setText(download.name);
        downloadHolder.progressBar.setIndeterminate(false);
        downloadHolder.progressBar.setMax(download.size);
        return convertView;
    }

public static class DownloadHolder
{
    ProgressBar progressBar;
    TextView label;
}

   }

DownloadViewクラス

import android.app.ListActivity;
import android.os.Bundle;

public class DownloadsView extends ListActivity
{
   public static DownloadsAdapter DOWNLOADS = null;

@Override
    protected void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      DOWNLOADS = new DownloadsAdapter(this, R.layout.download_item);
      setListAdapter(DOWNLOADS);
      //TEST
      /*
      DownloadsView.addDownload("Lol", 232);
      DownloadsView.addDownload("fsfs", 123);
     */ 
 }

    public static void addDownload(String name, int size)
    {   
      DOWNLOADS.add(new Download(name, size));
    }  
}
4

2 に答える 2

2

さて、ここに行きます...

package com.skype.transfer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.skype.api.Transfer;
import com.skype.ref.R;

/*****
 * This class is in charge of displaying ongoing transfers in a ListView
 * <p>
 * The methods of relevance are {@link #getItem()}, {@link #getCount()} and
 * {@link #getView()}.
 * 
 * @author Aleksandar Milenkovic
 */
public class TransferArrayAdapter extends ArrayAdapter<Transfer>
{
    private ArrayList<Transfer> values      = null;
    private Vector<Boolean>     selectedStates;
    private Context             context;

    private ImageView           transferType;
    private TextView            filename;
    private ProgressBar         progress;
    private TextView            details;

    private static final String ASSETS_DIR  = "images/";
    private static final String LOGTAG      = "TransferArrayAdapter";

    /**
     * The default constructor which is invoked to create the current transfers'
     * array adapter
     * 
     * @param context
     *            the application context
     * @param textViewResourceId
     *            The resource ID for a layout file containing a TextView to use
     *            when instantiating views.
     * @param objects
     *            the backing array populated by Buddy objects to be displayed.
     * @see {@link ArrayAdapter}<T>
     */
    public TransferArrayAdapter(Context context, int textViewResourceId, ArrayList<Transfer> objects)
    {
        super(context, textViewResourceId, objects);
        this.context = context;
        this.values = objects;
        //      selectedStates = new Vector<Boolean>();
        //      clearSelectedState();
    }

    /**
     * How many items are in the data set represented by this Adapter.
     * 
     * @return the trimmed size of the backing array.
     */
    @Override
    public int getCount()
    {
        this.values.trimToSize();
        return this.values.size();
    }

    /**
     * Get the data item associated with the specified position in the data set.
     * 
     * @param index
     *            Position of the item whose data we want within the adapter's
     *            data set.
     * @return the Transfer item at the indicated position in the backing array
     */
    @Override
    public Transfer getItem(int index)
    {
        if (index <= getCount())    //IndexOutOfBoundsException fix
            return this.values.get(index);
        return this.values.get(values.size());
    }

    /**
     * This method is used to generate views to be used in the ListView. This
     * the method that defines how data will look and be represented throughout
     * the UI.
     * 
     * @param position
     *            The position of the item that is being placed / The position
     *            of the item within the adapter's data set of the item whose
     *            view we want.
     *            <p>
     * @param convertView
     *            The old view to reuse, if possible. Note: You should check
     *            that this view is non-null and of an appropriate type before
     *            using. If it is not possible to convert this view to display
     *            the correct data, this method can create a new view.
     *            Heterogeneous lists can specify their number of view types, so
     *            that this View is always of the right type (see
     *            getViewTypeCount() and getItemViewType(int))
     *            <p>
     * @param parent
     *            The parent that this view will eventually be attached to
     * @return the view that defines how this Buddy object is represented in the
     *         ListView / A View corresponding to the data at the specified
     *         position.
     * 
     * @see {@link BaseAdapter#getView(int, View, ViewGroup)}
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;

        if (row == null)
        {
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.transfer_item, parent, false);
            //          row.setTag(convertView);
        }

        Transfer file = getItem(position);
        //      Log.d(LOGTAG, "getView(): file at position "+position+"= "+file);
        if (file == null) return row;

        transferType = (ImageView) row.findViewById(R.id.transfer_type);
        filename = (TextView) row.findViewById(R.id.transfer_filename);
        progress = (ProgressBar) row.findViewById(R.id.transfer_progress);
        details = (TextView) row.findViewById(R.id.transfer_details);

        //filename, progress, details
        filename.setText(FileUtils.getFilenameFor(file));
        progress.setProgress(FileUtils.getProgressFor(file));

        switch (FileUtils.getStatusFor(file))
        {
            case PAUSED:
                details.setText("Paused");
                break;

            case WAITING_FOR_ACCEPT:
                details.setText("Waiting...");
                break;

            case CANCELLED:
            case CANCELLED_BY_REMOTE:
                details.setText("Canceled");
                break;

            default:
                details.setText(FileUtils.getTransferInfo(file));
                break;
        }

        //image stuff
        String imgFilePath = ASSETS_DIR;
        switch (FileUtils.getTransferTypeFor(file))
        {
            case INCOMING:
                imgFilePath += "incoming_file.png";
                break;

            case OUTGOING:
                imgFilePath += "outcoming_file.png";
                break;
        }

        try
        {
            Bitmap bitmap = BitmapFactory.decodeStream(this.context.getResources().getAssets().open(imgFilePath));
            transferType.setImageBitmap(bitmap);
        } catch (IOException e)
        {
            Log.e(LOGTAG + "Exception", e.getMessage());
            e.printStackTrace();
            Log.e(LOGTAG, "Error while setting " + FileUtils.getFilenameFor(file) + " type icon to: " + imgFilePath);
        }

        return row;
    }

    /**
     * This method is used to clear all selection states on the view's children.
     */
    public void clearSelectedState()
    {
        selectedStates.clear();
        for (int i = 0; i <= getCount(); i++)
        {
            selectedStates.add(Boolean.valueOf(false));
        }
    }

    /**
     * This method is used to make a certain position 'selected'.
     * <p>
     * After setting selection, notifyDataSetChanged() will be called.
     * 
     * @param position
     *            the position to select
     */
    public void setSelectedState(int position)
    {
        //clear selected state vector
        clearSelectedState();
        //set selected position
        selectedStates.set(position, Boolean.valueOf(true));
        //refresh adapter to redraw focus
        notifyDataSetChanged();
    }

    /**
     * Method to use to update a Transfer's UI
     * 
     * @param file
     *            file to display
     * @param overRelay
     *            is the transfer going over a relay
     */
    public void updateTransfer(Transfer file, boolean overRelay)
    {
        //TODO: use overRelay to indicate slower transfer

        int index = values.indexOf(file);

        if (index < 0)
        {
            notifyDataSetChanged();
            return;
        }

        getView(index, null, null).postInvalidate();
        notifyDataSetChanged();
    }

}

FileUtilsはあなたのファイルと互換性がないので、その実装はあなたに任せます。ただし、転送を送信した連絡先にマップします。これは単なるユーティリティハッシュマップヘルパークラスです:)

これがXMLです

着信ファイル.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayout1"
    android:layout_width="500dp"
    android:layout_height="200dp" >

    <TextView
        android:id="@+id/incoming_files_subtitle1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:text="@string/incoming_file" />

    <TextView
        android:id="@+id/incoming_files_detail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/incoming_files_subtitle1"
        android:layout_marginLeft="5dp"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/incoming_files_subtitle2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/incoming_files_detail"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="5dp"
        android:text="@string/saved_at" />

    <EditText
        android:id="@+id/incoming_files_path"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/incoming_files_subtitle2"
        android:inputType="textUri" />

    <Button
        android:id="@+id/incoming_files_browse"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/incoming_files_path"
        android:layout_toRightOf="@+id/incoming_files_path"
        android:text="@string/browse" />

    <Button
        android:id="@+id/incoming_files_accept"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginTop="2dp"
        android:text="@string/accept" />

    <Button
        android:id="@+id/incoming_files_cancel"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginTop="2dp"
        android:text="@string/cancel" />

</RelativeLayout>

transfer_dialog.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <LinearLayout 
        android:id="@+id/transfer_button_holder"
        android:orientation="horizontal"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="10dp" >

    <Button 
        android:id="@+id/btn_transfer_incoming"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/incoming"/>

    <Button 
        android:id="@+id/btn_transfer_outgoing"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/outgoing"/>

    <Button 
        android:id="@+id/btn_transfer_finished"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/finished"/>

    <Button 
        android:id="@+id/btn_transfer_all"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/view_all"/>

    </LinearLayout>


    <ListView
        android:id="@+id/transfer_list"
        android:layout_width="fill_parent"
        android:layout_height="650dp"
        android:choiceMode="singleChoice"
        android:layout_below="@+id/transfer_button_holder"
        android:listSelector="@drawable/selector_list" />

    <Button
        android:id="@+id/btn_cancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text="@string/cancel" />

</RelativeLayout>

transfer_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/transfer_type"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_gravity="left|center_vertical"
        android:layout_margin="5dp" />

    <TextView
        android:id="@+id/transfer_filename"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/transfer_type"
        android:layout_alignParentTop="true"
        android:gravity="center_horizontal"
        android:text="@string/empty_string" />

    <ProgressBar
        android:id="@+id/transfer_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/transfer_filename"
        android:layout_toRightOf="@+id/transfer_type"
        android:max="100" />

    <TextView
        android:id="@+id/transfer_details"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/transfer_progress"
        android:layout_toRightOf="@+id/transfer_type"
        android:layout_alignParentBottom="true"
        android:text="@string/empty_string" />

</RelativeLayout>

ダイアログコードを転送します。適応が必要です。

private void showTransfersDialog()
    {
        transferDialog = new Dialog(context);
        transferDialog.setContentView(R.layout.transfer_dialog);

        transferDialog.setTitle(R.string.transfer_manager);
        transferDialog.setCancelable(true);

        //set up buttons
        Button btnQuit = (Button) transferDialog.findViewById(R.id.btn_cancel);
        Button btnShowIncoming = (Button) transferDialog.findViewById(R.id.btn_transfer_incoming);
        Button btnShowOutgoing = (Button) transferDialog.findViewById(R.id.btn_transfer_outgoing);
        Button btnShowFinished = (Button) transferDialog.findViewById(R.id.btn_transfer_finished);
        Button btnShowAll = (Button) transferDialog.findViewById(R.id.btn_transfer_all);

        transferList = (ListView) transferDialog.findViewById(R.id.transfer_list);
        registerForContextMenu(transferList);
        transferList.setOnItemClickListener(new ListView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                showTransferFileDialog(transferAdapter.getItem(position));
            }
        });
        transferAdapter = new TransferArrayAdapter(SkypeKitVideoDemo.this, android.R.layout.simple_list_item_1,
                FileUtils.getAllTransfersAsList());

        Log.d(LOGTAG, "transferAdapter = " + transferAdapter);

        Log.d(LOGTAG, "setting adapter to transfers = " + transferList);
        transferList.setAdapter(transferAdapter);

        btnQuit.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                transferDialog.dismiss();
                transferDialog = null;
                transferList = null;
            }
        });

        btnShowAll.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                transferAdapter = new TransferArrayAdapter(SkypeKitVideoDemo.this, android.R.layout.simple_list_item_1, FileUtils
                        .getAllTransfersAsList());
                transferList.setAdapter(transferAdapter);
            }
        });

        btnShowIncoming.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                transferAdapter = new TransferArrayAdapter(SkypeKitVideoDemo.this, android.R.layout.simple_list_item_1, FileUtils
                        .getAllTransfersOfTypeAsList(Transfer.Type.INCOMING));
                transferList.setAdapter(transferAdapter);
            }
        });

        btnShowOutgoing.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                transferAdapter = new TransferArrayAdapter(SkypeKitVideoDemo.this, android.R.layout.simple_list_item_1, FileUtils
                        .getAllTransfersOfTypeAsList(Transfer.Type.OUTGOING));
                transferList.setAdapter(transferAdapter);
            }
        });

        btnShowFinished.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                transferAdapter = new TransferArrayAdapter(SkypeKitVideoDemo.this, android.R.layout.simple_list_item_1, FileUtils
                        .getAllFinishedTransfers());
                transferList.setAdapter(transferAdapter);
            }
        });

        //now that the dialog is set up, it's time to show it    
        transferDialog.show();

        return;
    }

受信ファイルダイアログ:

private void showIncomingFileDialog(final Conversation convo, final Transfer[] transfers, final int index)
    {
        incomingFileDialog = new Dialog(context);
        incomingFileDialog.setContentView(R.layout.incoming_file);

        if (index >= transfers.length) return;  //sanity check

        String sender = transfers[index].getPartnerHandle();
        String filename = transfers[index].getFileName();

        incomingFileDialog.setTitle("INCOMING FILES(" + (index + 1) + " / " + transfers.length + ") FROM " + sender);
        incomingFileDialog.setCancelable(false);

        //set up controls
        TextView detail = (TextView) incomingFileDialog.findViewById(R.id.incoming_files_detail);
        final EditText pathToFile = (EditText) incomingFileDialog.findViewById(R.id.incoming_files_path);
        Button btnBrowse = (Button) incomingFileDialog.findViewById(R.id.incoming_files_browse);
        Button btnAccept = (Button) incomingFileDialog.findViewById(R.id.incoming_files_accept);
        Button btnCancel = (Button) incomingFileDialog.findViewById(R.id.incoming_files_cancel);
        pathToFile.setText(savingPath + filename);

        detail.setText(filename + "\t- " + FileUtils.getFilesizeFrom(transfers[index]));

        btnAccept.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View arg0)
            {
                float size = Float.parseFloat(transfers[index].getFileSize());

                if (size < getAvailableFreeSpace())
                {
                    transfers[index].accept(pathToFile.getText().toString());
                    FileUtils.addTransferFrom(convo, transfers[index]);
                } else
                    showFileTooBigDialog(convo, transfers[index], pathToFile.getText().toString());

                if (index == transfers.length - 1)
                {
                    incomingFileDialog.dismiss();
                } else
                {
                    incomingFileDialog.dismiss();
                    showIncomingFileDialog(convo, transfers, index + 1);
                }

            }
        });

        btnCancel.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                transfers[index].cancel();
                if (index == transfers.length - 1)
                {
                    incomingFileDialog.dismiss();
                } else
                {
                    incomingFileDialog.dismiss();
                    showIncomingFileDialog(convo, transfers, index + 1);
                }

            }
        });

        btnBrowse.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                showFolderPicker(convo, transfers, index);
                incomingFileDialog.dismiss();
            }
        });

        //now that the dialog is set up, it's time to show it    
        incomingFileDialog.show();

        return;
    }

これらはFileUtilsに依存していますが、ある程度の努力を払えば、会話を文字列に交換し、ファイルまたはある種のラッパーに転送することができます:)

于 2012-11-05T15:52:31.717 に答える
1

ListView内のアイテムだけを更新することはできませんAndroid。が表示されているデータを更新して、Adapterを呼び出す必要notifyDataSetChanged()がありますAdapter

于 2012-11-04T20:14:37.240 に答える