2

I am replicating an iOS app into Android. The app has a "wallet" screen with credit card animations, see video of the app in iOS, below. How can I achieve similar functionality in Android?

Here is a video of the iOS wallet in action -> Wallet iOS demo

I need to replicate these functions:

  1. Listview with animation when choosing a card (when you click a card it switch place with the new one)
  2. Click on main card (big one) makes a bounce animation and goes to detail of card.
  3. Swipe left on main card also goes to detail of card.

This is the library used in iOS to make it work is GLStackedViewController.

Wallet

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
RonEskinder
  • 527
  • 8
  • 24

2 Answers2

2

I ended up making it from scratch, no libraries needed and using regular ListView.

In the cardHolder fragment that holds all the cards, when clicking on first item(0) the card bounces and then goes to detail fragment, and when click on other item that is not the first just change the listview order and update the adapter, one thing missing here is the animation of the cards between clicks, still a WIP.

    // Click event for single list row
    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                final int position, long id) {

            Log.d(TAG, "Position: " + position);

            final FragmentAccount fragment = new FragmentAccount();

            // Fisrt card
            if (position == 0) {
                // Animated bounce effect
                Animation anim = AnimationUtils.loadAnimation(view.getContext(), R.anim.expand_in);
                view.startAnimation(anim);

                // delay click event (anim duration) and go to new fragment
                new Handler().postDelayed(new Runnable() {

                    public void run() {
                        if (listBalance.get(position).get(TAG_ACCOUNT_BANKACCOUNTS_ID) != null) {
                            ((GlobalVars) getActivity().getApplication()).setIdBankAccount(Integer.valueOf(listBalance.get(position).get(TAG_ACCOUNT_BANKACCOUNTS_ID)));
                            ((GlobalVars) getActivity().getApplication()).setIdGiftCard(0);
                            ((GlobalVars) getActivity().getApplication()).setCardBalance("");
                        } else if (listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_ID) != null) {
                            ((GlobalVars) getActivity().getApplication()).setIdBankAccount(0);
                            ((GlobalVars) getActivity().getApplication()).setIdGiftCard(Integer.valueOf(listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_ID)));
                            ((GlobalVars) getActivity().getApplication()).setCardBalance(listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_BALANCE));
                        } else {
                            ((GlobalVars) getActivity().getApplication()).setIdBankAccount(0);
                            ((GlobalVars) getActivity().getApplication()).setIdGiftCard(0);
                            ((GlobalVars) getActivity().getApplication()).setCardBalance(listBalance.get(position).get(TAG_ACCOUNT_X111_BALANCE));
                        }

                        ((BaseContainerFragment) getParentFragment()).replaceFragment(fragment, true);
                    }

                }, anim.getDuration());
            }
            // Item is not the first, so trade places with first one
            else {
                HashMap<String, String> tmp = listBalance.get(0);
                Log.d(TAG, tmp.toString());

                listBalance.set(0, listBalance.get(position));
                listBalance.set(position, tmp);
                adapter.notifyDataSetChanged();
                updateAdapter();
            }
        }
    });

Bounce Animation

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

    <scale
        android:duration="50"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.1"
        android:toYScale="1.1" />

    <scale
        android:duration="50"
        android:fromXScale="0.9"
        android:fromYScale="0.9"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="50"
        android:toXScale="1.0"
        android:toYScale="1.0" />
</set>

Adapter

public View getView(final int position, View convertView, ViewGroup parent) {
    vi = convertView;

    if (layout == "account") {

        if (convertView == null) {
            vi = inflater.inflate(R.layout.activity_account_list_item, null);
        }

        TextView transaction_name = (TextView) vi.findViewById(R.id.account_name);
        TextView transaction_address = (TextView) vi.findViewById(R.id.account_address);
        TextView transaction_date = (TextView) vi.findViewById(R.id.account_date);
        ImageView transaction_icon = (ImageView) vi.findViewById(R.id.account_image);

        HashMap<String, String> transactions = new HashMap<String, String>();
        transactions = data.get(position);

        // Setting all values in listview
        transaction_name.setText(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_NAME));
        transaction_address.setText(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_ADDRESS));
        transaction_date.setText(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_DATE));
        imageLoader.DisplayImage(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_ICON), transaction_icon);
    }

    else if (layout == "balance") {
        String[] color = { "56a77a","568fa7" ,"f8d243", "8fb63c", "114783", "e1ac47", "58ACFA", "819FF7", "5858FA",
                "AC58FA", "FE9A2E", "FA5858", "FA5882"};
        //Log.d("COLOR", "Color: " + color[position] + " | Position: " +position);
        if (convertView == null && position == 0) {
            vi = inflater.inflate(R.layout.activity_cardholder_list_item_first, null);

            TextView saldo = (TextView) vi.findViewById(R.id.tvSaldo);
            TextView balance_idBankAccount = (TextView) vi.findViewById(R.id.idBankAccount);
            TextView balance_idGiftCard = (TextView) vi.findViewById(R.id.idGiftCard);
            TextView balance_amount = (TextView) vi.findViewById(R.id.tvAmount);
            TextView balance_cardNumber = (TextView) vi.findViewById(R.id.tvCardNumber);
            TextView balance_expDate = (TextView) vi.findViewById(R.id.tvExpDate);
            ImageView balance_foto = (ImageView) vi.findViewById(R.id.ivLogo);
            LinearLayout background = (LinearLayout) vi.findViewById(R.id.background);
            GradientDrawable bgShape = (GradientDrawable)background.getBackground();

            HashMap<String, String> balance = new HashMap<String, String>();
            balance = data.get(position);

            // Setting all values in listview
            balance_idBankAccount.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_ID));
            balance_idGiftCard.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_GIFTCARDS_ID));
            if(balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE) == null){
                if(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_TYPE).equals("1")){
                    balance_amount.setText("CREDITO");
                } else {
                    balance_amount.setText("DEBITO");
                }
                String card = balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_CARDNUMBER);
                card = "**** **** **** " + card.substring(card.length() - 4, card.length());
                balance_cardNumber.setText(card);
                if (saldo != null) {
                    saldo.setText("");
                }
            } else {
                balance_amount.setText("$ " + balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE));
                balance_expDate.setText("");
                balance_cardNumber.setText("");
            }
            imageLoader.DisplayImage(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_FOTO), balance_foto);


            bgShape.setColor(Color.GREEN);

            if(color != null){
                bgShape.setColor(Integer.parseInt(color[position], 16) + 0xFF000000);
            }
        }
        // set layout for the next items
        else if (convertView == null && position != 0) {
            vi = inflater.inflate(R.layout.activity_cardholder_list_item, null);

            TextView saldo = (TextView) vi.findViewById(R.id.tvSaldo);
            TextView balance_idBankAccount = (TextView) vi.findViewById(R.id.idBankAccount);
            TextView balance_idGiftCard = (TextView) vi.findViewById(R.id.idGiftCard);
            TextView balance_amount = (TextView) vi.findViewById(R.id.tvAmount);
            ImageView balance_foto = (ImageView) vi.findViewById(R.id.ivLogo);
            LinearLayout background = (LinearLayout) vi.findViewById(R.id.background);
            GradientDrawable bgShape = (GradientDrawable)background.getBackground();

            HashMap<String, String> balance = new HashMap<String, String>();
            balance = data.get(position);

            // Setting all values in listview
            balance_idBankAccount.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_ID));
            balance_idGiftCard.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_GIFTCARDS_ID));

            if(balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE) == null){
                if(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_TYPE).equals("1")){
                    balance_amount.setText("CREDITO");
                } else {
                    balance_amount.setText("DEBITO");
                }
                saldo.setText("");
            } else {
                balance_amount.setText("$ " + balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE));
            }
            imageLoader.DisplayImage(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_FOTO), balance_foto);

            if(color[position] != null){
                bgShape.setColor(Integer.parseInt(color[position], 16) + 0xFF000000);
            }
        }
    }
}
RonEskinder
  • 527
  • 8
  • 24
1

If I were you I would use something similar to an expandable listview, which is a kind of listview in the android library.

Basically, you would need to make the following changes to the listview, to get it working like the video you have posted about iOS.

  1. Move the selected item to the first position in the expandible listview once it has been selected.
  2. code a DialogActivity which will display the details once the item is selected again.

A working example of an expandible listview can be seen in the link here

Hope this helps :)

Community
  • 1
  • 1
Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79