Created
December 5, 2017 17:27
-
-
Save efemoney/e03ea19e10fa106e3bb79dd06dd2eef0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.devone.haute.ui; | |
import android.app.ActivityManager; | |
import android.content.Context; | |
import android.content.DialogInterface; | |
import android.content.Intent; | |
import android.content.IntentFilter; | |
import android.graphics.Typeface; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.os.Bundle; | |
import android.support.v4.content.ContextCompat; | |
import android.support.v4.view.ViewPager; | |
import android.support.v7.app.AlertDialog; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.Toolbar; | |
import android.text.Editable; | |
import android.text.SpannableStringBuilder; | |
import android.text.Spanned; | |
import android.text.TextUtils; | |
import android.util.SparseArray; | |
import android.view.LayoutInflater; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.Button; | |
import android.widget.ProgressBar; | |
import android.widget.Toast; | |
import com.devone.haute.BuildConfig; | |
import com.devone.haute.R; | |
import com.devone.haute.data.RadioIds; | |
import com.devone.haute.data.Subscription; | |
import com.devone.haute.data.model.Promo; | |
import com.devone.haute.databinding.DialogEnterCouponBinding; | |
import com.devone.haute.databinding.SubscriptionCardBinding; | |
import com.devone.haute.firebase.Firebase; | |
import com.devone.haute.ui.extra.BulletSpan; | |
import com.devone.haute.ui.extra.HorizontalLineSpan; | |
import com.devone.haute.ui.widget.SubrcriptionRadioGroup; | |
import com.devone.haute.ui.widget.SubscriptionFontButton; | |
import com.devone.haute.ui.widget.SubscriptionRadioButton; | |
import com.devone.haute.ui.widget.TitleLogoToolbar; | |
import com.devone.haute.util.FontCache; | |
import com.devone.haute.util.FontPath; | |
import com.devone.haute.util.IabBroadcastReceiver; | |
import com.devone.haute.util.IabHelper; | |
import com.devone.haute.util.IabResult; | |
import com.devone.haute.util.Inventory; | |
import com.devone.haute.util.Purchase; | |
import com.devone.haute.util.SimpleTextWatcher; | |
import com.devone.haute.util.SkuDetails; | |
import com.google.firebase.database.DataSnapshot; | |
import com.google.firebase.database.DatabaseError; | |
import com.google.firebase.database.DatabaseReference; | |
import com.google.firebase.database.ValueEventListener; | |
import java.util.Arrays; | |
import java.util.concurrent.TimeUnit; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import static com.devone.haute.databinding.SubscriptionCardBinding.inflate; | |
import static com.devone.haute.firebase.Firebase.getCurrentUserSubOverrideRef; | |
import static com.devone.haute.util.FontPath.lookup; | |
public class SubscriptionActivity extends AppCompatActivity implements | |
IabHelper.OnIabSetupFinishedListener, | |
IabHelper.OnIabPurchaseFinishedListener, | |
IabHelper.QueryInventoryFinishedListener, | |
IabBroadcastReceiver.IabBroadcastListener { | |
public static final String SKU_SUB_PRO = "haute.subscription.pro.2"; | |
public static final String SKU_SUB_ELITE = "haute.subscription.elite.4"; | |
private static final int REQUEST_PAY = 1000; | |
int progressCount; | |
ViewPager mPager; | |
PagerAdapter mAdapter; | |
ProgressBar progress; | |
SubrcriptionRadioGroup mRadios; | |
private IabHelper helper; | |
private IabBroadcastReceiver iabBroadcastReceiver; | |
private ValueEventListener subsListener = new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
hideProgress(); | |
if (dataSnapshot.getValue() == null) return; | |
Subscription sub = dataSnapshot.getValue(Subscription.class); | |
if (sub == null) { | |
Toast.makeText(SubscriptionActivity.this.getApplicationContext(), | |
R.string.error_no_subscription, Toast.LENGTH_LONG).show(); | |
finish(); | |
return; | |
} | |
int subValue = sub.getValue(); | |
int radioId = RadioIds.forSubscriptionValue(subValue); | |
SubscriptionRadioButton radio = (SubscriptionRadioButton) mRadios.findViewById(radioId); | |
if (radio != null) { | |
mRadios.clearSubscribed(); // Clear previous subscribed | |
radio.setSubscribed(true); | |
} | |
if (mAdapter.map != null && mAdapter.map.get(subValue) != null) { | |
SubscriptionFontButton button = mAdapter.map.get(subValue).subButton; | |
if (button != null) { | |
button.setEnabled(false); | |
button.setSubscribed(true); | |
} | |
} | |
mPager.setCurrentItem(subValue >> 1, false); // Update pager position | |
} | |
@Override | |
public void onCancelled(DatabaseError firebaseError) { | |
hideProgress(); | |
Toast.makeText(SubscriptionActivity.this, "Error: " + firebaseError.getMessage(), Toast.LENGTH_LONG).show(); | |
hideProgress(); | |
} | |
}; | |
private OnSubscriptionClickListener listener = new OnSubscriptionClickListener() { | |
@Override | |
public void onSubscriptionClicked(final int value) { | |
final Purchase current = mAdapter.getCurrentPurchase(); | |
DatabaseReference ref = Firebase.getCurrentUserSubOverrideRef(); | |
Firebase.addListenerForOneUpdate(ref, new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
if (dataSnapshot.getValue() == null) { | |
doNormalOnSUbscribe(value, current); | |
return; | |
} | |
long time = dataSnapshot.getValue(long.class); | |
if (time < System.currentTimeMillis()) { | |
doNormalOnSUbscribe(value, current); | |
return; | |
} | |
showCannotSubscribeDialog(); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
Toast.makeText( | |
SubscriptionActivity.this, | |
"Error retrieving subscriptions: " + databaseError.getMessage(), | |
Toast.LENGTH_SHORT | |
).show(); | |
doNormalOnSUbscribe(value, current); | |
} | |
}); | |
} | |
}; | |
private void showCannotSubscribeDialog() { | |
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Haute_Dialog); | |
TitleLogoToolbar title = new TitleLogoToolbar(builder.getContext()); | |
title.setTitleTextAppearance(builder.getContext(), R.style.MuliTextAppearance_Dialog_Title); | |
title.setTitle(R.string.cannot_subscribe); | |
builder.setCustomTitle(title).setView(R.layout.dialog_cannot_sub).show(); | |
} | |
private void doNormalOnSUbscribe(int value, Purchase current) { | |
if (value == Subscription.starter && current != null) { | |
showCancelSubDialog(); | |
return; | |
} | |
if (value == Subscription.starter) { | |
subscribeFor(Subscription.STARTER); | |
Firebase.addListenerForOneUpdate(Firebase.getCurrentUserSubRef(), subsListener); | |
return; | |
} | |
String sku = value == Subscription.pro ? SKU_SUB_PRO : SKU_SUB_ELITE; | |
try { | |
showProgress(); | |
helper.launchSubscriptionPurchaseFlow( | |
SubscriptionActivity.this, sku, | |
current == null ? null : Arrays.asList(current.getSku()), | |
REQUEST_PAY, | |
SubscriptionActivity.this, | |
getExtraDataForUser() | |
); | |
} catch (IabHelper.IabAsyncInProgressException e) { | |
hideProgress(); | |
e.printStackTrace(); | |
} | |
} | |
@SuppressWarnings("ConstantConditions") @Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) setTaskDescription( | |
new ActivityManager.TaskDescription(null, null, | |
ContextCompat.getColor(this, R.color.colorBackgroundSub)) | |
); | |
Firebase.init(); | |
setContentView(R.layout.activity_subscription); | |
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | |
if (toolbar != null) { | |
toolbar.inflateMenu(R.menu.menu_coupon); | |
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { | |
@Override | |
public boolean onMenuItemClick(MenuItem item) { | |
SubscriptionActivity.this.showCouponDialog(); | |
return true; | |
} | |
}); | |
toolbar.setNavigationOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
SubscriptionActivity.this.finish(); | |
} | |
}); | |
} | |
progress = (ProgressBar) findViewById(R.id.progress); | |
mPager = (ViewPager) findViewById(R.id.pager); | |
mRadios = (SubrcriptionRadioGroup) findViewById(R.id.radios); | |
mPager.setOffscreenPageLimit(2); | |
mRadios.clearCheck(); | |
setupPagerWithRadios(); | |
showProgress(); | |
DatabaseReference ref = getCurrentUserSubOverrideRef(); | |
if (ref == null) { initBilling(); return; } | |
Firebase.addListenerForOneUpdate(ref, new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
if (dataSnapshot.getValue() == null) { | |
initBilling(); | |
return; | |
} | |
long time = dataSnapshot.getValue(long.class); | |
if (time < System.currentTimeMillis()) { | |
initBilling(); | |
return; | |
} | |
initAdapter(null, null, null); // We have no purchase data | |
Firebase.addListenerForOneUpdate(Firebase.getCurrentUserSubRef(), subsListener); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
Toast.makeText(SubscriptionActivity.this, "Error retrieving subscriptions", Toast.LENGTH_SHORT).show(); | |
Firebase.addListenerForOneUpdate(Firebase.getCurrentUserSubRef(), subsListener); | |
} | |
}); | |
} | |
private void showCouponDialog() { | |
LayoutInflater inf = LayoutInflater.from(this); | |
final DialogEnterCouponBinding binding = DialogEnterCouponBinding.inflate(inf, null, false); | |
final AlertDialog d = new AlertDialog.Builder(this, R.style.Haute_Dialog) | |
.setView(binding.getRoot()) | |
.show(); | |
binding.coupon.addTextChangedListener(new SimpleTextWatcher() { | |
@Override | |
public void afterTextChanged(Editable editable) { | |
binding.positive.setEnabled(!TextUtils.isEmpty(editable)); | |
} | |
}); | |
binding.positive.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
DatabaseReference ref = Firebase.getCurrentUserSubOverrideRef(); | |
Firebase.addListenerForOneUpdate(ref, new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
if (dataSnapshot.getValue() == null) { | |
redeemCoupon(d, binding, binding.coupon.getText().toString()); | |
return; | |
} | |
long time = dataSnapshot.getValue(long.class); | |
if (time < System.currentTimeMillis()) { | |
redeemCoupon(d, binding, binding.coupon.getText().toString()); | |
return; | |
} | |
showCannotSubscribeDialog(); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
Toast.makeText( | |
SubscriptionActivity.this, | |
"Error retrieving subscriptions: " + databaseError.getMessage(), | |
Toast.LENGTH_SHORT | |
).show(); | |
} | |
}); | |
} | |
}); | |
} | |
private void redeemCoupon(final AlertDialog d, final DialogEnterCouponBinding binding, final String coupon) { | |
binding.coupon.getText().clear(); | |
binding.coupon.setVisibility(View.GONE); | |
binding.label.setVisibility(View.GONE); | |
binding.negative.setVisibility(View.GONE); | |
binding.positive.setVisibility(View.GONE); | |
binding.progress.setVisibility(View.VISIBLE); | |
DatabaseReference coupRef = Firebase.getRef("promos", coupon.toUpperCase()); | |
if (coupRef == null) { | |
showCouponError(d, binding, "Cannot find the specified promo."); | |
return; | |
} | |
Firebase.addListenerForOneUpdate(coupRef, new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
binding.progress.setVisibility(View.GONE); | |
if (dataSnapshot.getValue() == null) { | |
showCouponError(d, binding, "The specified promotion does not exist."); | |
return; | |
} | |
final Promo promo = dataSnapshot.getValue(Promo.class); | |
binding.title.setVisibility(View.VISIBLE); | |
binding.title.setText(promo.getName()); | |
binding.desc.setVisibility(View.VISIBLE); | |
binding.desc.setText(promo.getDescription()); | |
binding.positive.setVisibility(View.VISIBLE); | |
binding.positive.setEnabled(true); | |
binding.positive.setText("Confirm"); | |
binding.positive.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
//noinspection WrongConstant | |
Subscription sub = Subscription.forValue(promo.getSubValue()); | |
DatabaseReference ref = Firebase.getCurrentUserSubOverrideRef(); | |
if (ref == null) { | |
showCouponError(d, binding, "Could not find user."); | |
return; | |
} | |
long now = System.currentTimeMillis(); | |
long duration = TimeUnit.DAYS.toMillis(promo.getDurationDays()); | |
long then = now + duration; | |
ref.setValue(then); | |
subscribeFor(sub); | |
Firebase.addListenerForOneUpdate(Firebase.getCurrentUserSubRef(), subsListener); | |
d.dismiss(); | |
} | |
}); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
binding.progress.setVisibility(View.GONE); | |
showCouponError(d, binding, "Cannot find the specified promo. Error: " + databaseError.getMessage()); | |
} | |
}); | |
} | |
private void showCouponError(final AlertDialog d, DialogEnterCouponBinding binding, String message) { | |
binding.progress.setVisibility(View.GONE); | |
binding.positive.setVisibility(View.GONE); | |
binding.title.setVisibility(View.GONE); | |
binding.desc.setVisibility(View.GONE); | |
binding.status.setVisibility(View.VISIBLE); | |
binding.negative.setVisibility(View.VISIBLE); | |
binding.status.setText(message); | |
binding.negative.setText("OK"); | |
binding.negative.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
d.dismiss(); | |
} | |
}); | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
if (iabBroadcastReceiver != null) unregisterReceiver(iabBroadcastReceiver); | |
if (helper != null) helper.disposeWhenFinished(); | |
helper = null; | |
} | |
private void setupPagerWithRadios() { | |
mPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { | |
@Override | |
public void onPageSelected(final int position) { | |
mRadios.check(position == 0 ? R.id.starter : position == 1 ? R.id.pro : R.id.elite); | |
} | |
}); | |
mRadios.setOnCheckedChangeListener(new SubrcriptionRadioGroup.OnCheckedChangeListener() { | |
@Override | |
public void onCheckedChanged(SubrcriptionRadioGroup group, int checkedId) { | |
mPager.setCurrentItem(checkedId == R.id.starter ? 0 : checkedId == R.id.pro ? 1 : 2, true); | |
} | |
}); | |
mPager.setPageTransformer(false, new ViewPager.PageTransformer() { | |
@Override | |
public void transformPage(View view, float position) { | |
if (position < -1) { | |
// [-Infinity,-1) This page is way off-screen to the left. | |
view.setAlpha(0.54f); | |
} else if (position <= 1) { | |
// [-1,1] | |
view.setAlpha(1 - (0.46f * (Math.abs(position)))); | |
} else { | |
// (1,+Infinity] This page is way off-screen to the right. | |
view.setAlpha(0.54f); | |
} | |
} | |
}); | |
} | |
private void initBilling() { | |
helper = new IabHelper(this, Subscription.B64ENCODED_PUBLIC_KEY); | |
helper.enableDebugLogging(BuildConfig.DEBUG, "HauteIabHelper"); | |
helper.startSetup(this); | |
} | |
private void initBillingWithoutUpdate() { | |
} | |
private String getExtraDataForUser() { | |
// Returns UID for now. Uid is unique per user | |
return Firebase.getCurrentUser().getUid(); | |
} | |
private Purchase getCurrentPurchase(Inventory inv) { | |
Purchase pro = inv.getPurchase(SKU_SUB_PRO); | |
Purchase elite = inv.getPurchase(SKU_SUB_ELITE); | |
if (pro != null && elite != null) { | |
Toast.makeText(this, "You have multiple subscriptions.", Toast.LENGTH_SHORT).show(); | |
} | |
return elite != null ? elite : pro != null ? pro : null; | |
} | |
private void subscribeFor(Subscription sub) { | |
//noinspection ConstantConditions | |
Firebase.getCurrentUserSubRef().setValue(sub); | |
} | |
private void showCancelSubDialog() { | |
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Haute_Dialog); | |
TitleLogoToolbar title = new TitleLogoToolbar(builder.getContext()); | |
title.setTitleTextAppearance(builder.getContext(), R.style.MuliTextAppearance_Dialog_Title); | |
title.setTitle(R.string.cancel_sub); | |
AlertDialog dialog = builder.setCustomTitle(title) | |
.setView(R.layout.dialog_cancel_sub) | |
.setPositiveButton("Open Play Store", new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialog12, int which) { | |
Uri playStoreUri = Uri.parse("https://play.google.com/store/account"); | |
SubscriptionActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, playStoreUri)); | |
} | |
}) | |
.setNeutralButton("Not Now", null) | |
.create() | |
; | |
dialog.setOnShowListener(new DialogInterface.OnShowListener() { | |
@Override | |
public void onShow(DialogInterface dialog1) { | |
Context context = ((AlertDialog) dialog1).getContext(); | |
Button positive = ((AlertDialog) dialog1).getButton(DialogInterface.BUTTON_POSITIVE); | |
Button neutral = ((AlertDialog) dialog1).getButton(DialogInterface.BUTTON_NEUTRAL); | |
Typeface muliFont = FontCache.get(context, lookup(FontPath.muli, Typeface.NORMAL)); | |
positive.setTypeface(muliFont); | |
neutral.setTypeface(muliFont); | |
} | |
}); | |
dialog.show(); | |
} | |
private void alert(String message) { | |
new AlertDialog.Builder(this, R.style.Haute_Dialog) | |
.setMessage(message) | |
.setPositiveButton("OK", null) | |
.show() | |
; | |
} | |
private void showProgress() { | |
if (progress != null && progressCount == 0) progress.setVisibility(View.VISIBLE); | |
progressCount++; | |
if (progressCount < 0) progressCount = 0; | |
} | |
private void hideProgress() { | |
progressCount--; | |
if (progress != null && progressCount == 0) progress.setVisibility(View.GONE); | |
if (progressCount < 0) progressCount = 0; | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
if (helper != null && helper.handleActivityResult(requestCode, resultCode, data)) { | |
return; | |
} | |
super.onActivityResult(requestCode, resultCode, data); | |
} | |
@Override | |
public void onIabSetupFinished(IabResult result) { | |
hideProgress(); | |
// Have we been disposed of in the meantime? If so, quit. | |
if (helper == null) return; | |
if (result.isFailure()) { | |
alert("Problem setting up in-app billing: " + result); | |
initAdapter(null, null, null); | |
return; | |
} | |
// Important: Dynamically register for broadcast messages about updated purchases. | |
// We register the receiver here instead of as a <receiver> in the Manifest | |
// because we always call getPurchases() at startup, so therefore we can ignore | |
// any broadcasts sent while the app isn't running. | |
// Note: registering this listener in an Activity is a bad idea, but is done here | |
// because this is a SAMPLE. Regardless, the receiver must be registered after | |
// IabHelper is setup, but before first call to getPurchases(). | |
iabBroadcastReceiver = new IabBroadcastReceiver(SubscriptionActivity.this); | |
IntentFilter broadcastFilter = new IntentFilter(IabBroadcastReceiver.ACTION); | |
registerReceiver(iabBroadcastReceiver, broadcastFilter); | |
// IAB is fully set up. Now, let's get an inventory of stuff we own. | |
try { | |
showProgress(); | |
helper.queryInventoryAsync( | |
true, // | |
null, | |
Arrays.asList(SKU_SUB_PRO, SKU_SUB_ELITE), | |
this | |
); | |
} catch (IabHelper.IabAsyncInProgressException e) { | |
hideProgress(); | |
alert("Error querying inventory. Another async operation in progress."); | |
} | |
} | |
@Override | |
public void onQueryInventoryFinished(IabResult result, Inventory inv) { | |
hideProgress(); | |
// Have we been disposed of in the meantime? If so, quit. | |
if (helper == null) return; | |
if (result.isFailure()) { | |
alert("Failed to query inventory: " + result); | |
initAdapter(null, null, null); | |
return; | |
} | |
Purchase purchase = getCurrentPurchase(inv); | |
SkuDetails pro = inv.getSkuDetails(SKU_SUB_PRO); | |
SkuDetails elite = inv.getSkuDetails(SKU_SUB_ELITE); | |
initAdapter(pro, elite, purchase); | |
Subscription sub = Subscription.STARTER; | |
if (purchase != null && purchase.getPurchaseState() == 0) { | |
if (purchase.getSku().equals(SKU_SUB_PRO)) sub = Subscription.PRO; | |
if (purchase.getSku().equals(SKU_SUB_ELITE)) sub = Subscription.ELITE; | |
} | |
subscribeFor(sub); // Update subscription state | |
//Update UI | |
Firebase.addListenerForOneUpdate(Firebase.getCurrentUserSubRef(), subsListener); | |
} | |
private void initAdapter(SkuDetails pro, SkuDetails elite, Purchase purchase) { | |
mAdapter = new PagerAdapter(pro, elite); | |
mAdapter.setCurrentPurchase(purchase); | |
mPager.setAdapter(mAdapter); | |
} | |
@Override | |
public void onIabPurchaseFinished(IabResult result, Purchase purchase) { | |
hideProgress(); | |
// Have we been disposed of in the meantime? If so, quit. | |
if (helper == null) return; | |
if (result.isFailure()) { | |
alert("Error purchasing: " + result); | |
return; | |
} | |
if (!verifyPayload(purchase)) { | |
alert("Error purchasing. Authenticity verification failed."); | |
return; | |
} | |
Subscription sub = Subscription.STARTER; | |
if (purchase.getSku().equals(SKU_SUB_PRO)) sub = Subscription.PRO; | |
if (purchase.getSku().equals(SKU_SUB_ELITE)) sub = Subscription.ELITE; | |
// Purchased | |
if (purchase.getPurchaseState() == 0) subscribeFor(sub); | |
mAdapter.setCurrentPurchase(purchase); | |
mAdapter.notifyDataSetChanged(); | |
Firebase.addListenerForOneUpdate(Firebase.getCurrentUserSubRef(), subsListener); | |
} | |
@Override | |
public void receivedBroadcast() { | |
} | |
private boolean verifyPayload(Purchase info) { | |
// Checks that is is this user that actually made the purchase | |
return android.text.TextUtils.equals(Firebase.getCurrentUser().getUid(), info.getDeveloperPayload()); | |
} | |
private class PagerAdapter extends android.support.v4.view.PagerAdapter { | |
static final int NUM_PAGES = 3; | |
private final String[] headings = new String[]{ | |
"Features Include:", | |
"Includes all Starter features, and:", | |
"Includes all Pro features, and:" | |
}; | |
private final String[] prices = new String[]{ | |
"Free Forever", | |
"$10/Month", | |
"$15/Month" | |
}; | |
private final Pattern patternBullet = Pattern.compile("[a-zA-Z0-9 ]+\\n"); | |
private final Pattern patternLine = Pattern.compile("~"); | |
private final String[] descriptions = new String[]{ | |
"Unlimited Albums\n~\n" + | |
"5 Customer Profiles\n~\n" + | |
"Save customers full body measurement\n~\n", | |
"Unlimited Albums\n~\n" + | |
"50 Customer Profiles\n~\n" + | |
"Add watermark when sharing photos\n~\n" + | |
"Save customers full body measurement\n~\n", | |
"Unlimited Albums\n~\n" + | |
"Unlimited Customer Profiles\n~\n" + | |
"Add watermark when sharing photos\n~\n" + | |
"Save customers full body measurement\n~\n" + | |
"Custom measurement templates\n~\n" | |
}; | |
private final SkuDetails proDetails; | |
private final SkuDetails eliteDetails; | |
private Purchase current; | |
SparseArray<SubscriptionCardBinding> map = new SparseArray<>(); | |
PagerAdapter(SkuDetails proDetails, SkuDetails eliteDetails) { | |
this.proDetails = proDetails; | |
this.eliteDetails = eliteDetails; | |
if (proDetails != null) prices[1] = proDetails.getPrice() + "/Month"; | |
if (eliteDetails != null) prices[2] = eliteDetails.getPrice() + "/Month"; | |
} | |
@Override | |
public int getItemPosition(Object object) { | |
return POSITION_NONE; | |
} | |
@Override | |
public int getCount() { | |
return NUM_PAGES; | |
} | |
@Override | |
public Object instantiateItem(ViewGroup container, int position) { | |
Context context = container.getContext(); | |
LayoutInflater inflater = LayoutInflater.from(context); | |
SubscriptionCardBinding binding = inflate(inflater, container, false); | |
populate(context, binding, position); | |
container.addView(binding.getRoot()); | |
return binding.getRoot(); | |
} | |
private void populate(Context context, SubscriptionCardBinding binding, int position) { | |
@Subscription.Value int value = 1 << position; | |
Subscription subscription = Subscription.forValue(value); | |
String subscriptionName = subscription.getName(); | |
binding.subHead.setText(headings[position]); | |
binding.subPrice.setText(prices[position]); | |
binding.subDesc.setText(getSpannedDesc(context, descriptions[position])); | |
binding.subTitle.setText(getString(R.string.sub_title, subscriptionName)); | |
binding.subButton.setText(getString(R.string.sub_button, subscriptionName)); | |
binding.subButton.setTag(value); // Very important! | |
binding.subButton.setOnClickListener(listener); | |
map.put(value, binding); | |
} | |
private CharSequence getSpannedDesc(Context context, String desc) { | |
SpannableStringBuilder spanned = new SpannableStringBuilder(desc); | |
Matcher matcher = patternLine.matcher(desc); | |
while (matcher.find()) { | |
spanned.setSpan(new HorizontalLineSpan(context), | |
matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | |
} | |
matcher = patternBullet.matcher(desc); | |
while (matcher.find()) { | |
spanned.setSpan(new BulletSpan(context), | |
matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | |
} | |
return spanned; | |
} | |
@Override | |
public void destroyItem(ViewGroup container, int position, Object object) { | |
container.removeView((View) object); | |
@Subscription.Value int value = 1 << position; | |
map.remove(value); | |
} | |
@Override | |
public boolean isViewFromObject(View view, Object object) { | |
return view == object; | |
} | |
public Purchase getCurrentPurchase() { | |
return current; | |
} | |
public void setCurrentPurchase(Purchase current) { | |
this.current = current; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment