Skip to content

Commit

Permalink
Fixed issues with fragment management
Browse files Browse the repository at this point in the history
  • Loading branch information
erasmospunk committed Apr 24, 2016
1 parent 251545d commit 1e2bc95
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 155 deletions.
185 changes: 92 additions & 93 deletions wallet/src/main/java/com/coinomi/wallet/ui/AccountFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.view.ActionMode;
import android.view.LayoutInflater;
Expand All @@ -15,6 +14,7 @@
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.coinomi.core.uri.CoinURI;
import com.coinomi.core.uri.CoinURIParseException;
Expand All @@ -23,6 +23,7 @@
import com.coinomi.wallet.R;
import com.coinomi.wallet.WalletApplication;
import com.coinomi.wallet.util.Keyboard;
import com.coinomi.wallet.util.WeakHandler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -46,17 +47,21 @@ public class AccountFragment extends Fragment {
// want to re-render that if we go to the SendFragment and back
private static final int OFF_SCREEN_LIMIT = 2;

// Screen ids
private static final int RECEIVE = 0;
private static final int BALANCE = 1;
private static final int SEND = 2;

// Handler ids
private static final int SEND_TO_URI = 0;

private int currentScreen;
@Bind(R.id.pager) ViewPager viewPager;
NavigationDrawerFragment mNavigationDrawerFragment;
@Nullable private WalletAccount account;
private Listener listener;
private WalletApplication application;
private final Handler handler = new Handler();
private final MyHandler handler = new MyHandler(this);

public static AccountFragment getInstance() {
AccountFragment fragment = new AccountFragment();
Expand All @@ -70,15 +75,17 @@ public static AccountFragment getInstance(String accountId) {
return fragment;
}

public void setupArgs(String accountId) {
private void setupArgs(String accountId) {
getArguments().putString(Constants.ARG_ACCOUNT_ID, accountId);
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
setRetainInstance(true);

// TODO handle null account
account = application.getAccount(getArguments().getString(Constants.ARG_ACCOUNT_ID));
}

@Override
Expand All @@ -91,10 +98,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa

viewPager.setOffscreenPageLimit(OFF_SCREEN_LIMIT);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int pos, float posOffset, int posOffsetPixels) {
}

@Override
public void onPageSelected(int position) {
currentScreen = position;
Expand All @@ -116,11 +119,13 @@ public void onPageSelected(int position) {
}
}

@Override
public void onPageScrollStateChanged(int state) {
}
@Override public void onPageScrolled(int pos, float posOffset, int posOffsetPixels) { }
@Override public void onPageScrollStateChanged(int state) { }
});

viewPager.setAdapter(
new AppSectionsPagerAdapter(getActivity(), getChildFragmentManager(), account));

return view;
}

Expand All @@ -131,12 +136,6 @@ public void onDestroyView() {
super.onDestroyView();
}

@Override
public void onResume() {
super.onResume();
applyArguments();
}

@Override
public void onAttach(final Context context) {
super.onAttach(context);
Expand All @@ -148,6 +147,12 @@ public void onAttach(final Context context) {
}
}

@Override
public void onDetach() {
listener = null;
super.onDetach();
}

@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(ACCOUNT_CURRENT_SCREEN, currentScreen);
Expand All @@ -157,8 +162,10 @@ public void onSaveInstanceState(Bundle outState) {
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
currentScreen = savedInstanceState.getInt(ACCOUNT_CURRENT_SCREEN, BALANCE);
updateView();
} else {
currentScreen = BALANCE;
}
updateView();
super.onViewStateRestored(savedInstanceState);
}

Expand Down Expand Up @@ -192,67 +199,47 @@ private void updateView() {
goToItem(currentScreen, true);
}

public void applyArguments() {
Bundle args = getArguments();
if (args != null && args.containsKey(Constants.ARG_ACCOUNT_ID)) {
String accountId = args.getString(Constants.ARG_ACCOUNT_ID);
// If no account set or if it was changed
if (account == null || !account.getId().equals(accountId) ||
mustUpdatePagerAdapter(viewPager.getAdapter())) {
account = application.getAccount(accountId);
resetPagerAdapter();
}
}
}

private void resetPagerAdapter() {
if (account != null) {
PagerAdapter adapter = new AppSectionsPagerAdapter(getActivity(),
getFragmentManager(), account);
viewPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}

private boolean mustUpdatePagerAdapter(PagerAdapter adapter) {
if (adapter instanceof AppSectionsPagerAdapter) {
// If the fragment manager changed, must update the adapter
if (((AppSectionsPagerAdapter) adapter).fm == getFragmentManager()) {
return false;
}
}
return true;
}

@Nullable
public WalletAccount getAccount() {
return account;
}

public void setSendFromCoin(final CoinURI coinUri)
throws CoinURIParseException{
public void sendToUri(final CoinURI coinUri) {
if (viewPager != null) {
viewPager.setCurrentItem(SEND);
SendFragment f = getSendFragment();
if (f != null) {
f.updateStateFrom(coinUri);
} else {
log.warn("Expected fragment to be not null");
toastGenericError(getContext());
}
handler.sendMessage(handler.obtainMessage(SEND_TO_URI, coinUri));
} else {
// Should not happen
toastGenericError(getContext());
}
}

private void setSendToUri(CoinURI coinURI) {
if (viewPager != null) viewPager.setCurrentItem(SEND);
SendFragment f = getSendFragment();
if (f != null) {
try {
f.updateStateFrom(coinURI);
} catch (CoinURIParseException e) {
Toast.makeText(getContext(),
getString(R.string.scan_error, e.getMessage()),
Toast.LENGTH_LONG).show();
}
} else {
log.warn("Expected fragment to be not null");
toastGenericError(getContext());
}
}

@Nullable
private SendFragment getSendFragment() {
return (SendFragment) getFragment(getFragmentManager(), SEND);
return (SendFragment) getFragment(getChildFragmentManager(), SEND);
}

@Nullable
private static Fragment getFragment(FragmentManager fm, int item) {
if (fm.getFragments() == null) return null;

for (Fragment f : fm.getFragments()) {
switch (item) {
case RECEIVE:
Expand All @@ -271,26 +258,16 @@ private static Fragment getFragment(FragmentManager fm, int item) {
return null;
}


private static Fragment getFragmentOrCreate(FragmentManager fm, WalletAccount account, int item) {
Fragment f = getFragment(fm, item);

if (f == null) {
f = createFragment(account, item);
}

return f;
}

private static Fragment createFragment(WalletAccount account, int item) {
@SuppressWarnings({ "unchecked"})
private static <T extends Fragment> T createFragment(WalletAccount account, int item) {
String accountId = account.getId();
switch (item) {
case RECEIVE:
return AddressRequestFragment.newInstance(accountId);
return (T) AddressRequestFragment.newInstance(accountId);
case BALANCE:
return BalanceFragment.newInstance(accountId);
return (T) BalanceFragment.newInstance(accountId);
case SEND:
return SendFragment.newInstance(accountId);
return (T) SendFragment.newInstance(accountId);
default:
throw new RuntimeException("Cannot create fragment, unknown screen item: " + item);
}
Expand Down Expand Up @@ -325,25 +302,37 @@ public boolean resetSend() {
return false;
}

private static class AppSectionsPagerAdapter extends FragmentStatePagerAdapter {
final Context context;
final FragmentManager fm;
private final WalletAccount account;
private static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
private final String receiveTitle;
private final String sendTitle;
private final String balanceTitle;

private AddressRequestFragment request;
private SendFragment send;
private BalanceFragment balance;

private WalletAccount account;

public AppSectionsPagerAdapter(Context context, FragmentManager fm, WalletAccount account) {
super(fm);
this.context = context;
this.fm = fm;
receiveTitle = context.getString(R.string.wallet_title_request);
sendTitle = context.getString(R.string.wallet_title_send);
balanceTitle = context.getString(R.string.wallet_title_balance);
this.account = account;
}

@Override
public Fragment getItem(int i) {
switch (i) {
case RECEIVE:
if (request == null) request = createFragment(account, i);
return request;
case SEND:
if (send == null) send = createFragment(account, i);
return send;
case BALANCE:
return getFragmentOrCreate(fm, account, i);
if (balance == null) balance = createFragment(account, i);
return balance;
default:
throw new RuntimeException("Cannot get item, unknown screen item: " + i);
}
Expand All @@ -356,15 +345,25 @@ public int getCount() {
}

@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case RECEIVE:
return context.getString(R.string.wallet_title_request);
case SEND:
return context.getString(R.string.wallet_title_send);
case BALANCE:
default:
return context.getString(R.string.wallet_title_balance);
public CharSequence getPageTitle(int i) {
switch (i) {
case RECEIVE: return receiveTitle;
case SEND: return sendTitle;
case BALANCE: return balanceTitle;
default: throw new RuntimeException("Cannot get item, unknown screen item: " + i);
}
}
}

private static class MyHandler extends WeakHandler<AccountFragment> {
public MyHandler(AccountFragment ref) { super(ref); }

@Override
protected void weakHandleMessage(AccountFragment ref, Message msg) {
switch (msg.what) {
case SEND_TO_URI:
ref.setSendToUri((CoinURI) msg.obj);
break;
}
}
}
Expand Down
Loading

0 comments on commit 1e2bc95

Please sign in to comment.