Finished the new about screen. Also the DonationDialog loads its content now async.

This commit is contained in:
Karim Abou Zeid 2015-09-06 19:57:29 +02:00
commit 3d87e57856
13 changed files with 463 additions and 149 deletions

View file

@ -31,7 +31,6 @@ public class ChangelogDialog extends LeakDetectDialogFragment {
return new ChangelogDialog();
}
@SuppressLint("InflateParams")
@NonNull
@Override

View file

@ -0,0 +1,216 @@
package com.kabouzeid.gramophone.dialogs;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.ThemeSingleton;
import com.afollestad.materialdialogs.internal.MDTintHelper;
import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.SkuDetails;
import com.anjlab.android.iab.v3.TransactionDetails;
import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.util.ColorUtil;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class DonationDialog extends LeakDetectDialogFragment implements BillingProcessor.IBillingHandler {
public static final String TAG = DonationDialog.class.getSimpleName();
private static final int DONATION_PRODUCT_IDS = R.array.donation_ids;
private BillingProcessor billingProcessor;
public static DonationDialog create() {
return new DonationDialog();
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
billingProcessor = new BillingProcessor(getContext(), App.GOOGLE_PLAY_LICENSE_KEY, this);
@SuppressLint("InflateParams")
View customView = LayoutInflater.from(getContext()).inflate(R.layout.dialog_donation, null);
ProgressBar progressBar = ButterKnife.findById(customView, R.id.progress);
MDTintHelper.setTint(progressBar, ThemeSingleton.get().positiveColor.getDefaultColor());
return new MaterialDialog.Builder(getContext())
.title(R.string.support_development)
.customView(customView, false)
.build();
}
void donate(int i) {
final String[] ids = getResources().getStringArray(DONATION_PRODUCT_IDS);
billingProcessor.purchase(getActivity(), ids[i]);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onProductPurchased(String productId, TransactionDetails details) {
Toast.makeText(getContext(), R.string.thank_you, Toast.LENGTH_SHORT).show();
}
@Override
public void onPurchaseHistoryRestored() {
Toast.makeText(getContext(), R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show();
}
@Override
public void onBillingError(int errorCode, Throwable error) {
Log.e(TAG, "Billing error: code = " + errorCode, error);
}
@Override
public void onBillingInitialized() {
new Thread(new LoadAndDisplayPurchasesRunnable(this)).start();
}
@Override
public void onDestroy() {
if (billingProcessor != null) {
billingProcessor.release();
}
super.onDestroy();
}
static class LoadAndDisplayPurchasesRunnable implements Runnable {
WeakReference<DonationDialog> dialogWeakReference;
public LoadAndDisplayPurchasesRunnable(DonationDialog donationDialog) {
dialogWeakReference = new WeakReference<>(donationDialog);
}
@Override
public void run() {
try {
final DonationDialog donationDialog = dialogWeakReference.get();
final String[] ids = donationDialog.getResources().getStringArray(DONATION_PRODUCT_IDS);
final List<SkuDetails> skuDetailsList = donationDialog.billingProcessor.getPurchaseListingDetails(new ArrayList<>(Arrays.asList(ids)));
donationDialog.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (skuDetailsList == null || skuDetailsList.isEmpty()) {
donationDialog.dismiss();
return;
}
View customView = ((MaterialDialog) donationDialog.getDialog()).getCustomView();
if (customView != null) {
customView.findViewById(R.id.progress_container).setVisibility(View.GONE);
ListView listView = ButterKnife.findById(customView, R.id.list);
listView.setAdapter(new SkuDetailsAdapter(donationDialog, skuDetailsList));
listView.setVisibility(View.VISIBLE);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class SkuDetailsAdapter extends ArrayAdapter<SkuDetails> {
@LayoutRes
private static int LAYOUT_RES_ID = R.layout.item_donation_option;
DonationDialog donationDialog;
public SkuDetailsAdapter(@NonNull DonationDialog donationDialog, @NonNull List<SkuDetails> objects) {
super(donationDialog.getContext(), LAYOUT_RES_ID, objects);
this.donationDialog = donationDialog;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(LAYOUT_RES_ID, parent, false);
}
SkuDetails skuDetails = getItem(position);
ViewHolder viewHolder = new ViewHolder(convertView);
viewHolder.title.setText(skuDetails.title.replace("(Phonograph Music Player)", "").trim());
viewHolder.text.setText(skuDetails.description);
viewHolder.price.setText(skuDetails.priceText);
final boolean purchased = donationDialog.billingProcessor.isPurchased(skuDetails.productId);
int titleTextColor = purchased ? ColorUtil.resolveColor(getContext(), android.R.attr.textColorHint) : ColorUtil.resolveColor(getContext(), android.R.attr.textColorPrimary);
int contentTextColor = purchased ? titleTextColor : ColorUtil.resolveColor(getContext(), android.R.attr.textColorSecondary);
viewHolder.title.setTextColor(titleTextColor);
viewHolder.text.setTextColor(contentTextColor);
viewHolder.price.setTextColor(titleTextColor);
strikeThrough(viewHolder.title, purchased);
strikeThrough(viewHolder.text, purchased);
strikeThrough(viewHolder.price, purchased);
convertView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return purchased;
}
});
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
donationDialog.donate(position);
}
});
return convertView;
}
private static void strikeThrough(TextView textView, boolean strikeThrough) {
textView.setPaintFlags(strikeThrough ? textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG : textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
}
static class ViewHolder {
@Bind(R.id.title)
TextView title;
@Bind(R.id.text)
TextView text;
@Bind(R.id.price)
TextView price;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
}

View file

@ -1,13 +1,21 @@
package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.dialogs.ChangelogDialog;
import com.kabouzeid.gramophone.dialogs.DonationDialog;
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
import butterknife.Bind;
@ -16,9 +24,64 @@ import butterknife.ButterKnife;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class AboutActivity extends AbsBaseActivity {
public class AboutActivity extends AbsBaseActivity implements View.OnClickListener {
private static String GOOGLE_PLUS = "https://google.com/+KarimAbouZeid23697";
private static String TWITTER = "https://twitter.com/karim23697";
private static String GITHUB = "https://github.com/kabouzeid";
private static String WEBSITE = "http://kabouzeid.de/";
private static String REPORT_BUGS = "https://github.com/kabouzeid/phonograph-issue-tracker";
private static String GOOGLE_PLUS_COMMUNITY = "https://plus.google.com/u/0/communities/106227738496107108513";
private static String TRANSLATE = "https://phonograph.oneskyapp.com/collaboration/project?id=26521";
private static String RATE_ON_GOOGLE_PLAY = "https://play.google.com/store/apps/details?id=com.kabouzeid.gramophone";
private static String AIDAN_FOLLESTAD_GOOGLE_PLUS = "https://google.com/+AidanFollestad";
private static String AIDAN_FOLLESTAD_GITHUB = "https://github.com/afollestad";
private static String MICHAEL_COOK_GOOGLE_PLUS = "https://google.com/+michaelcook";
private static String MICHAEL_COOK_WEBSITE = "http://cookicons.co/";
private static String MAARTEN_CORPEL_GOOGLE_PLUS = "https://google.com/+MaartenCorpel";
private static String ALEKSANDAR_TESIC_GOOGLE_PLUS = "https://google.com/+aleksandartešić";
@Bind(R.id.toolbar)
Toolbar toolbar;
@Bind(R.id.app_version)
TextView appVersion;
@Bind(R.id.changelog)
LinearLayout changelog;
@Bind(R.id.add_to_google_plus_circles)
LinearLayout addToGooglePlusCircles;
@Bind(R.id.follow_on_twitter)
LinearLayout followOnTwitter;
@Bind(R.id.fork_on_git_hub)
LinearLayout forkOnGitHub;
@Bind(R.id.visit_website)
LinearLayout visitWebsite;
@Bind(R.id.report_bugs)
LinearLayout reportBugs;
@Bind(R.id.join_google_plus_community)
LinearLayout joinGooglePlusCommunity;
@Bind(R.id.translate)
LinearLayout translate;
@Bind(R.id.donate)
LinearLayout donate;
@Bind(R.id.rate_on_google_play)
LinearLayout rateOnGooglePlay;
@Bind(R.id.aidan_follestad_google_plus)
AppCompatButton aidanFollestadGooglePlus;
@Bind(R.id.aidan_follestad_git_hub)
AppCompatButton aidanFollestadGitHub;
@Bind(R.id.michael_cook_google_plus)
AppCompatButton michaelCookGooglePlus;
@Bind(R.id.michael_cook_website)
AppCompatButton michaelCookWebsite;
@Bind(R.id.maarten_corpel_google_plus)
AppCompatButton maartenCorpelGooglePlus;
@Bind(R.id.aleksandar_tesic_google_plus)
AppCompatButton aleksandarTesicGooglePlus;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -27,16 +90,49 @@ public class AboutActivity extends AbsBaseActivity {
setStatusBarTransparent();
ButterKnife.bind(this);
toolbar.setBackgroundColor(getThemeColorPrimary());
setSupportActionBar(toolbar);
//noinspection ConstantConditions
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setUpViews();
if (shouldColorNavigationBar())
setNavigationBarThemeColor();
setStatusBarThemeColor();
}
private void setUpViews() {
setUpToolbar();
setUpAppVersion();
setUpOnClickListeners();
}
private void setUpToolbar() {
toolbar.setBackgroundColor(getThemeColorPrimary());
setSupportActionBar(toolbar);
//noinspection ConstantConditions
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void setUpAppVersion() {
appVersion.setText(getCurrentVersionName(this));
}
private void setUpOnClickListeners() {
changelog.setOnClickListener(this);
addToGooglePlusCircles.setOnClickListener(this);
followOnTwitter.setOnClickListener(this);
forkOnGitHub.setOnClickListener(this);
visitWebsite.setOnClickListener(this);
reportBugs.setOnClickListener(this);
joinGooglePlusCommunity.setOnClickListener(this);
translate.setOnClickListener(this);
rateOnGooglePlay.setOnClickListener(this);
donate.setOnClickListener(this);
aidanFollestadGooglePlus.setOnClickListener(this);
aidanFollestadGitHub.setOnClickListener(this);
michaelCookGooglePlus.setOnClickListener(this);
michaelCookWebsite.setOnClickListener(this);
maartenCorpelGooglePlus.setOnClickListener(this);
aleksandarTesicGooglePlus.setOnClickListener(this);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
@ -47,12 +143,55 @@ public class AboutActivity extends AbsBaseActivity {
}
private static String getCurrentVersionName(@NonNull final Context context) {
String versionName;
try {
versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
return "Unknown";
e.printStackTrace();
}
return versionName;
return "0.0.0";
}
@Override
public void onClick(View v) {
if (v == changelog) {
ChangelogDialog.create().show(getSupportFragmentManager(), "CHANGELOG_DIALOG");
} else if (v == addToGooglePlusCircles) {
openUrl(GOOGLE_PLUS);
} else if (v == followOnTwitter) {
openUrl(TWITTER);
} else if (v == forkOnGitHub) {
openUrl(GITHUB);
} else if (v == visitWebsite) {
openUrl(WEBSITE);
} else if (v == reportBugs) {
openUrl(REPORT_BUGS);
} else if (v == joinGooglePlusCommunity) {
openUrl(GOOGLE_PLUS_COMMUNITY);
} else if (v == translate) {
openUrl(TRANSLATE);
} else if (v == rateOnGooglePlay) {
openUrl(RATE_ON_GOOGLE_PLAY);
} else if (v == donate) {
DonationDialog.create().show(getSupportFragmentManager(), "DONATION_DIALOG");
} else if (v == aidanFollestadGooglePlus) {
openUrl(AIDAN_FOLLESTAD_GOOGLE_PLUS);
} else if (v == aidanFollestadGitHub) {
openUrl(AIDAN_FOLLESTAD_GITHUB);
} else if (v == michaelCookGooglePlus) {
openUrl(MICHAEL_COOK_GOOGLE_PLUS);
} else if (v == michaelCookWebsite) {
openUrl(MICHAEL_COOK_WEBSITE);
} else if (v == maartenCorpelGooglePlus) {
openUrl(MAARTEN_CORPEL_GOOGLE_PLUS);
} else if (v == aleksandarTesicGooglePlus) {
openUrl(ALEKSANDAR_TESIC_GOOGLE_PLUS);
}
}
private void openUrl(String url) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}

View file

@ -7,14 +7,12 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.provider.MediaStore;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
@ -27,30 +25,21 @@ import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialcab.MaterialCab;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.ThemeSingleton;
import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.BillingProcessor.IBillingHandler;
import com.anjlab.android.iab.v3.SkuDetails;
import com.anjlab.android.iab.v3.TransactionDetails;
import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.PagerAdapter;
import com.kabouzeid.gramophone.dialogs.ChangelogDialog;
import com.kabouzeid.gramophone.dialogs.CreatePlaylistDialog;
import com.kabouzeid.gramophone.dialogs.DonationDialog;
import com.kabouzeid.gramophone.dialogs.SleepTimerDialog;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.SearchQueryHelper;
@ -76,14 +65,12 @@ import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
public class MainActivity extends AbsSlidingMusicPanelActivity
implements KabViewsDisableAble, CabHolder, IBillingHandler {
implements KabViewsDisableAble, CabHolder {
public static final String TAG = MainActivity.class.getSimpleName();
@ -105,8 +92,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
private PagerAdapter pagerAdapter;
private MaterialCab cab;
private BillingProcessor billingProcessor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -127,8 +112,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
setNavigationBarThemeColor();
setStatusBarThemeColor();
billingProcessor = new BillingProcessor(this, App.GOOGLE_PLAY_LICENSE_KEY, this);
checkChangelog();
}
@ -237,7 +220,7 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
showDonationDialog();
DonationDialog.create().show(getSupportFragmentManager(), "DONATION_DIALOG");
}
}, 300);
break;
@ -598,124 +581,4 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
e.printStackTrace();
}
}
static class SkuDetailsAdapter extends ArrayAdapter<SkuDetails> {
@LayoutRes
private static int LAYOUT_RES_ID = R.layout.item_donation_option;
public SkuDetailsAdapter(@NonNull MainActivity mainActivity, @NonNull List<SkuDetails> objects) {
super(mainActivity, LAYOUT_RES_ID, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(LAYOUT_RES_ID, parent, false);
}
SkuDetails skuDetails = getItem(position);
ViewHolder viewHolder = new ViewHolder(convertView);
viewHolder.title.setText(skuDetails.title.replace("(Phonograph Music Player)", "").trim());
viewHolder.text.setText(skuDetails.description);
viewHolder.price.setText(skuDetails.priceText);
final boolean purchased = ((MainActivity) getContext()).billingProcessor.isPurchased(skuDetails.productId);
int titleTextColor = purchased ? ColorUtil.resolveColor(getContext(), android.R.attr.textColorHint) : ColorUtil.resolveColor(getContext(), android.R.attr.textColorPrimary);
int contentTextColor = purchased ? titleTextColor : ColorUtil.resolveColor(getContext(), android.R.attr.textColorSecondary);
viewHolder.title.setTextColor(titleTextColor);
viewHolder.text.setTextColor(contentTextColor);
viewHolder.price.setTextColor(titleTextColor);
strikeThrough(viewHolder.title, purchased);
strikeThrough(viewHolder.text, purchased);
strikeThrough(viewHolder.price, purchased);
convertView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return purchased;
}
});
return convertView;
}
private static void strikeThrough(TextView textView, boolean strikeThrough) {
textView.setPaintFlags(strikeThrough ? textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG : textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
}
static class ViewHolder {
@Bind(R.id.title)
TextView title;
@Bind(R.id.text)
TextView text;
@Bind(R.id.price)
TextView price;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
private void showDonationDialog() {
billingProcessor.loadOwnedPurchasesFromGoogle();
final String[] ids = getResources().getStringArray(R.array.donation_ids);
List<SkuDetails> skuDetailsList = billingProcessor.getPurchaseListingDetails(new ArrayList<>(Arrays.asList(ids)));
if (skuDetailsList == null) return;
new MaterialDialog.Builder(this)
.title(R.string.support_development)
.adapter(new SkuDetailsAdapter(this, skuDetailsList), new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence charSequence) {
materialDialog.dismiss();
donate(i);
}
}).show();
}
private void donate(int i) {
final String[] ids = getResources().getStringArray(R.array.donation_ids);
billingProcessor.purchase(MainActivity.this, ids[i]);
}
@Override
public void onProductPurchased(String productId, TransactionDetails details) {
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show();
}
@Override
public void onPurchaseHistoryRestored() {
// ignore
}
@Override
public void onBillingError(int errorCode, Throwable error) {
Log.e(TAG, "Billing error: code = " + errorCode, error);
}
@Override
public void onBillingInitialized() {
// ignore
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
protected void onDestroy() {
if (billingProcessor != null) {
billingProcessor.release();
}
super.onDestroy();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

View file

@ -150,6 +150,48 @@
</LinearLayout>
<LinearLayout
android:id="@+id/rate_on_google_play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?rect_selector"
android:clickable="true"
android:gravity="center_vertical"
android:minHeight="@dimen/md_listitem_height"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<android.support.v7.internal.widget.TintImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_play_shopping_bag_white_24dp"
android:tint="?android:textColorSecondary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="32dp"
android:layout_marginStart="32dp"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingTop="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rate_on_google_play"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rate_on_google_play_summary"
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/donate"
android:layout_width="match_parent"

View file

@ -0,0 +1,50 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/progress_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:paddingBottom="@dimen/md_content_padding_top"
android:paddingLeft="@dimen/md_dialog_frame_margin"
android:paddingRight="@dimen/md_dialog_frame_margin"
android:paddingTop="@dimen/md_content_padding_top">
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:gravity="start"
android:paddingLeft="16dp"
android:text="@string/loading_products"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
tools:ignore="RtlHardcoded,RtlSymmetry" />
</LinearLayout>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:divider="@null"
android:dividerHeight="0dp"
android:paddingBottom="@dimen/md_content_padding_bottom"
android:paddingTop="@dimen/md_content_padding_top"
android:scrollbarStyle="outsideOverlay"
android:visibility="gone" />
</LinearLayout>

View file

@ -2,6 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?rect_selector"
android:orientation="horizontal"
android:paddingBottom="@dimen/md_simplelistitem_padding_top"
android:paddingEnd="@dimen/md_dialog_frame_margin"

View file

@ -175,6 +175,7 @@
<string name="back">back</string>
<string name="support_development">Support development</string>
<string name="thank_you">Thank you!</string>
<string name="restored_previous_purchases">Restored previous purchases.</string>
<string name="play_store_illustration_by">Play Store illustration by</string>
<string name="version">Version</string>
<string name="application">Application</string>
@ -189,6 +190,8 @@
<string name="join_community_summary">If you need help or have questions, the Phonograph community on Google Plus is a good place to go.</string>
<string name="translate">Translate</string>
<string name="translate_summary">Help translating Phonograph to your native language.</string>
<string name="rate_on_google_play">Rate</string>
<string name="rate_on_google_play_summary">Leave a positive rating on Google Play if you like Phonograph.</string>
<string name="donate">Donate</string>
<string name="donate_summary">If you think I deserve to get paid for my work, you can leave me a few dollars here.</string>
<string name="aidan_follestad_summary">For the theme engine and some other great stuff.</string>
@ -196,4 +199,5 @@
<string name="maarten_corpel_summary">For making the Play Store illustration and the empty album cover.</string>
<string name="aleksandar_tesic_summary">For helping me with the design.</string>
<string name="website">Website</string>
<string name="loading_products">Loading products…</string>
</resources>