Add the download/install progress bar

This commit is contained in:
mvp76 2016-11-21 17:01:03 +01:00
parent b2d363b947
commit d02ea05865
2 changed files with 161 additions and 22 deletions

View File

@ -40,7 +40,7 @@ import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ListView; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -67,6 +67,7 @@ import org.fdroid.fdroid.views.LinearLayoutManagerSnapHelper;
import org.fdroid.fdroid.views.ScreenShotsRecyclerViewAdapter; import org.fdroid.fdroid.views.ScreenShotsRecyclerViewAdapter;
import org.fdroid.fdroid.views.ShareChooserDialog; import org.fdroid.fdroid.views.ShareChooserDialog;
import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -225,6 +226,8 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
private ArrayList<Apk> mVersions; private ArrayList<Apk> mVersions;
private boolean mShowVersions; private boolean mShowVersions;
private HeaderViewHolder mHeaderView;
public AppDetailsRecyclerViewAdapter(Context context) { public AppDetailsRecyclerViewAdapter(Context context) {
mContext = context; mContext = context;
updateItems(); updateItems();
@ -300,6 +303,10 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
uriIsSetAndCanBeOpened(mApp.flattrID); uriIsSetAndCanBeOpened(mApp.flattrID);
} }
public HeaderViewHolder getHeaderView() {
return mHeaderView;
}
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEWTYPE_HEADER) { if (viewType == VIEWTYPE_HEADER) {
@ -343,6 +350,7 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
int viewType = getItemViewType(position); int viewType = getItemViewType(position);
if (viewType == VIEWTYPE_HEADER) { if (viewType == VIEWTYPE_HEADER) {
final HeaderViewHolder vh = (HeaderViewHolder) holder; final HeaderViewHolder vh = (HeaderViewHolder) holder;
mHeaderView = vh;
ImageLoader.getInstance().displayImage(mApp.iconUrlLarge, vh.iconView, vh.displayImageOptions); ImageLoader.getInstance().displayImage(mApp.iconUrlLarge, vh.iconView, vh.displayImageOptions);
vh.titleView.setText(mApp.name); vh.titleView.setText(mApp.name);
if (!TextUtils.isEmpty(mApp.author)) { if (!TextUtils.isEmpty(mApp.author)) {
@ -418,6 +426,19 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
} }
vh.buttonPrimaryView.setEnabled(true); vh.buttonPrimaryView.setEnabled(true);
} }
if (!TextUtils.isEmpty(mActiveDownloadUrlString)) {
vh.buttonLayout.setVisibility(View.GONE);
vh.progressLayout.setVisibility(View.VISIBLE);
} else {
vh.buttonLayout.setVisibility(View.VISIBLE);
vh.progressLayout.setVisibility(View.GONE);
}
vh.progressCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelInstall();
}
});
/*TextView currentVersion = (TextView) view.findViewById(R.id.current_version); /*TextView currentVersion = (TextView) view.findViewById(R.id.current_version);
if (!appDetails.getApks().isEmpty()) { if (!appDetails.getApks().isEmpty()) {
@ -619,6 +640,14 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
} }
} }
@Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
if (holder instanceof HeaderViewHolder) {
mHeaderView = null;
}
super.onViewRecycled(holder);
}
@Override @Override
public int getItemCount() { public int getItemCount() {
return mItems.size(); return mItems.size();
@ -640,8 +669,14 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
final TextView summaryView; final TextView summaryView;
final TextView descriptionView; final TextView descriptionView;
final TextView descriptionMoreView; final TextView descriptionMoreView;
final View buttonLayout;
final Button buttonPrimaryView; final Button buttonPrimaryView;
final Button buttonSecondaryView; final Button buttonSecondaryView;
final View progressLayout;
final ProgressBar progressBar;
final TextView progressLabel;
final TextView progressPercent;
final View progressCancel;
final DisplayImageOptions displayImageOptions; final DisplayImageOptions displayImageOptions;
HeaderViewHolder(View view) { HeaderViewHolder(View view) {
@ -652,8 +687,14 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
summaryView = (TextView) view.findViewById(R.id.summary); summaryView = (TextView) view.findViewById(R.id.summary);
descriptionView = (TextView) view.findViewById(R.id.description); descriptionView = (TextView) view.findViewById(R.id.description);
descriptionMoreView = (TextView) view.findViewById(R.id.description_more); descriptionMoreView = (TextView) view.findViewById(R.id.description_more);
buttonLayout = view.findViewById(R.id.button_layout);
buttonPrimaryView = (Button) view.findViewById(R.id.primaryButtonView); buttonPrimaryView = (Button) view.findViewById(R.id.primaryButtonView);
buttonSecondaryView = (Button) view.findViewById(R.id.secondaryButtonView); buttonSecondaryView = (Button) view.findViewById(R.id.secondaryButtonView);
progressLayout = view.findViewById(R.id.progress_layout);
progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
progressLabel = (TextView) view.findViewById(R.id.progress_label);
progressPercent = (TextView) view.findViewById(R.id.progress_percent);
progressCancel = view.findViewById(R.id.progress_cancel);
displayImageOptions = new DisplayImageOptions.Builder() displayImageOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true) .cacheInMemory(true)
.cacheOnDisk(true) .cacheOnDisk(true)
@ -694,6 +735,37 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
buttonSecondaryView.setTransformationMethod(allCapsTransformation); buttonSecondaryView.setTransformationMethod(allCapsTransformation);
descriptionMoreView.setTransformationMethod(allCapsTransformation); descriptionMoreView.setTransformationMethod(allCapsTransformation);
} }
public void setProgress(int bytesDownloaded, int totalBytes, int resIdString) {
if (bytesDownloaded == 0 && totalBytes == 0) {
// Remove progress bar
progressLayout.setVisibility(View.GONE);
buttonLayout.setVisibility(View.VISIBLE);
} else {
progressBar.setMax(totalBytes);
progressBar.setProgress(bytesDownloaded);
progressBar.setIndeterminate(totalBytes == -1);
if (resIdString != 0) {
progressLabel.setText(resIdString);
progressPercent.setText("");
} else if (totalBytes > 0 && bytesDownloaded >= 0) {
float percent = bytesDownloaded * 100 / totalBytes;
progressLabel.setText(Utils.getFriendlySize(bytesDownloaded) + " / " + Utils.getFriendlySize(totalBytes));
NumberFormat format = NumberFormat.getPercentInstance();
format.setMaximumFractionDigits(0);
progressPercent.setText(format.format(percent / 100));
} else if (bytesDownloaded >= 0) {
progressLabel.setText(Utils.getFriendlySize(bytesDownloaded));
progressPercent.setText("");
}
// Make sure it's visible
if (progressLayout.getVisibility() != View.VISIBLE) {
progressLayout.setVisibility(View.VISIBLE);
buttonLayout.setVisibility(View.GONE);
}
}
}
} }
public class ScreenShotsViewHolder extends RecyclerView.ViewHolder { public class ScreenShotsViewHolder extends RecyclerView.ViewHolder {
@ -987,6 +1059,12 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
InstallManagerService.queue(this, mApp, apk); InstallManagerService.queue(this, mApp, apk);
} }
private void cancelInstall() {
if (!TextUtils.isEmpty(mActiveDownloadUrlString)) {
InstallManagerService.cancel(this, mActiveDownloadUrlString);
}
}
/** /**
* Queue for uninstall based on the instance variable {@link #app} * Queue for uninstall based on the instance variable {@link #app}
*/ */
@ -1056,18 +1134,18 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) { switch (intent.getAction()) {
case Downloader.ACTION_STARTED: case Downloader.ACTION_STARTED:
//if (headerFragment != null) { if (mAdapter.getHeaderView() != null) {
// headerFragment.startProgress(); mAdapter.getHeaderView().setProgress(-1, -1, R.string.download_pending);
//} }
break; break;
case Downloader.ACTION_PROGRESS: case Downloader.ACTION_PROGRESS:
//if (headerFragment != null) { if (mAdapter.getHeaderView() != null) {
// headerFragment.updateProgress(intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1), mAdapter.getHeaderView().setProgress(intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1),
// intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1)); intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1), 0);
//} }
break; break;
case Downloader.ACTION_COMPLETE: case Downloader.ACTION_COMPLETE:
// Starts the install process one the download is complete. // Starts the install process once the download is complete.
cleanUpFinishedDownload(); cleanUpFinishedDownload();
mLocalBroadcastManager.registerReceiver(installReceiver, mLocalBroadcastManager.registerReceiver(installReceiver,
Installer.getInstallIntentFilter(intent.getData())); Installer.getInstallIntentFilter(intent.getData()));
@ -1094,16 +1172,21 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) { switch (intent.getAction()) {
case Installer.ACTION_INSTALL_STARTED: case Installer.ACTION_INSTALL_STARTED:
//headerFragment.startProgress(false); if (mAdapter.getHeaderView() != null) {
//headerFragment.showIndeterminateProgress(getString(R.string.installing)); mAdapter.getHeaderView().setProgress(-1, -1, R.string.installing);
}
break; break;
case Installer.ACTION_INSTALL_COMPLETE: case Installer.ACTION_INSTALL_COMPLETE:
//headerFragment.removeProgress(); if (mAdapter.getHeaderView() != null) {
mAdapter.getHeaderView().setProgress(0, 0, 0); // Remove
}
unregisterInstallReceiver(); unregisterInstallReceiver();
onAppChanged(); onAppChanged();
break; break;
case Installer.ACTION_INSTALL_INTERRUPTED: case Installer.ACTION_INSTALL_INTERRUPTED:
//headerFragment.removeProgress(); if (mAdapter.getHeaderView() != null) {
mAdapter.getHeaderView().setProgress(0, 0, 0); // Remove
}
onAppChanged(); onAppChanged();
String errorMessage = String errorMessage =
@ -1146,17 +1229,21 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) { switch (intent.getAction()) {
case Installer.ACTION_UNINSTALL_STARTED: case Installer.ACTION_UNINSTALL_STARTED:
//headerFragment.startProgress(false); if (mAdapter.getHeaderView() != null) {
//headerFragment.showIndeterminateProgress(getString(R.string.uninstalling)); mAdapter.getHeaderView().setProgress(-1, -1, R.string.uninstalling);
}
break; break;
case Installer.ACTION_UNINSTALL_COMPLETE: case Installer.ACTION_UNINSTALL_COMPLETE:
//headerFragment.removeProgress(); if (mAdapter.getHeaderView() != null) {
mAdapter.getHeaderView().setProgress(0, 0, 0); // Remove
}
onAppChanged(); onAppChanged();
unregisterUninstallReceiver(); unregisterUninstallReceiver();
break; break;
case Installer.ACTION_UNINSTALL_INTERRUPTED: case Installer.ACTION_UNINSTALL_INTERRUPTED:
//headerFragment.removeProgress(); if (mAdapter.getHeaderView() != null) {
mAdapter.getHeaderView().setProgress(0, 0, 0); // Remove
}
String errorMessage = String errorMessage =
intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE);
@ -1221,9 +1308,9 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
*/ */
private void cleanUpFinishedDownload() { private void cleanUpFinishedDownload() {
mActiveDownloadUrlString = null; mActiveDownloadUrlString = null;
//if (headerFragment != null) { if (mAdapter.getHeaderView() != null) {
// headerFragment.removeProgress(); mAdapter.getHeaderView().setProgress(0, 0, 0); // Remove
//} }
unregisterDownloaderReceiver(); unregisterDownloaderReceiver();
} }

View File

@ -56,14 +56,66 @@
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="Author" /> tools:text="Author" />
<RelativeLayout
android:id="@+id/progress_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/icon"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true">
<ImageView
android:id="@+id/progress_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:src="@android:drawable/ic_menu_close_clear_cancel"
/>
<TextView
android:id="@+id/progress_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:text="@string/downloading"
/>
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/progress_cancel"
android:layout_toStartOf="@id/progress_cancel"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:text=""
/>
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/progress_cancel"
android:layout_toStartOf="@id/progress_cancel"
android:layout_below="@id/progress_label"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
/>
</RelativeLayout>
<LinearLayout <LinearLayout
android:id="@+id/button_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/icon" android:layout_below="@id/icon"
android:layout_toEndOf="@id/icon" android:layout_toEndOf="@id/icon"
android:layout_toRightOf="@id/icon" android:layout_toRightOf="@id/icon"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"> android:layout_alignParentRight="true"
android:visibility="gone"
>
<Button <Button
android:id="@+id/secondaryButtonView" android:id="@+id/secondaryButtonView"