0

I'm new to android programming. I have been trying to make Reminder app that takes Time, Date and Description as Inputs.

I want to add a swipe action to the card. Initially, the Card shows time and date, but when the user swipes on the card, the content in the card must change, it should completely show a new layout which has a TextView containing Description in it.

I have searched everywhere, but all of them have given about removing or moving the card in the RecyclerView.

What I want is, how can I dynamically change the content(or layout) in the card with animation using swipe action?

this is my Card layout card_view.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout `enter code here`xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="170dp">

<android.support.v7.widget.CardView
    android:layout_height="150dp"
    android:layout_width="320dp"
    android:id="@+id/card_view"
    card_view:cardCornerRadius="16dp"
    card_view:cardElevation="2dp"
    >


    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:padding="10dp"
        android:orientation="vertical"
        android:background="@color/blue_color">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00:00"
            android:fontFamily="sans-serif-light"
            android:id="@+id/cardTime"
            android:textSize="@dimen/textview_fontsize"
            android:textColor="@color/textview_color"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="DESCRIPTION"
            android:fontFamily="sans-serif-light"
            android:id="@+id/description"
            android:textSize="@dimen/textview_fontsize"
            android:textColor="@color/textview_color"
            android:visibility="gone"
            />

        <TextView
            android:text=""
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/cardTime"
            android:layout_marginStart="12dp"
            android:layout_marginTop="17dp"
            android:id="@+id/cardPeriod"
            android:textColor="@color/textview_color"
            android:fontFamily="sans-serif-light"/>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/textview_color"
            android:layout_alignBottom="@+id/cardTime"
            android:id="@+id/time_line" />


        <TextView
            android:text="09/01/1997"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentStart="true"
            android:layout_marginStart="20dp"
            android:id="@+id/cardDate"
            android:textColor="@color/textview_color"
            android:fontFamily="sans-serif-light"
            android:textSize="@dimen/date_fontsize"/>


    </RelativeLayout>


</android.support.v7.widget.CardView>

MainActivity.java

public class MainActivity extends AppCompatActivity implements AlarmDialog.AlarmDialogListener {

ArrayList<CardGen> cardsList = new ArrayList<CardGen>();
RecyclerView recyclerView;
CardAdapter cardAdapter = new CardAdapter(cardsList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);




@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    recyclerView = (RecyclerView) findViewById(R.id.cardList);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setAdapter(cardAdapter);




    ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            int position = viewHolder.getAdapterPosition();
            CardAdapter.CardViewHolder holder = (CardAdapter.CardViewHolder) viewHolder;

            if (direction == ItemTouchHelper.LEFT){

                    holder.timeView.setVisibility(View.GONE);
                    holder.description.setVisibility(View.VISIBLE);

            } else {

            }
        }

        @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {


            if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){


            }
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    };
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);




}


public void createAlarm(View view){

    DialogFragment dialogFragment = new AlarmDialog();
    dialogFragment.show(getFragmentManager(), "AlarmDialog");
}


@Override
public void onDialogPositiveClick(DialogFragment dialog) {
    Dialog dialog1 =  dialog.getDialog();
    TimePicker timePicker = (TimePicker) dialog1.findViewById(R.id.timePicker);
    int hour = timePicker.getHour();
    String tempHour = Integer.toString(hour);
    String minute = Integer.toString(timePicker.getMinute());
    if(minute.length()==1){minute = "0" + minute;}
    Toast.makeText(this, tempHour, Toast.LENGTH_SHORT).show();


    System.out.println("this is adapter begin");

    CardGen cardGen = new CardGen();
    if(hour>12){tempHour = Integer.toString(hour-12);}
    else if(hour==0){tempHour="12";}

    if(tempHour.length()==1){tempHour = "0"+tempHour;}
    cardGen.hour = tempHour+":"+minute;
    if(hour>=12){cardGen.period="PM";}else{cardGen.period="AM";}

    cardGen.fragmentManager = getFragmentManager();
    cardAdapter.addList(cardGen);

    System.out.println(Integer.toString(cardsList.size()));
    System.out.println("this is the middle");





    System.out.println("this is the end");

}

@Override
public void onDialogNegativeClick(DialogFragment dialog) {

}

}

RecyclerAdapter (CardAdapter.java)

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder>  {

private ArrayList<CardGen> cardsList;

public CardAdapter(ArrayList<CardGen> cardsList){
    this.cardsList = cardsList;


}

@Override
public int getItemCount() {
    return cardsList.size();
}



@Override
public void onBindViewHolder(final CardViewHolder holder, int position) {

    final CardGen cardGen = cardsList.get(position);
    holder.timeView.setText(cardGen.hour);

    holder.periodView.setText(cardGen.period);
    final TextView temp = holder.dateView;
    holder.dateView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            DateSelection newFragment = new DateSelection();
            newFragment.setElements(temp);


            newFragment.show(cardGen.fragmentManager, "datePicker");
        }
    });



}




@Override
public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cards, parent, false);
    return new CardViewHolder(itemView);
}


public void addList(CardGen card){
    cardsList.add(card);
    notifyItemInserted(cardsList.size());
}

public void removeList(int position){
    cardsList.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, cardsList.size());
}

public class CardViewHolder extends RecyclerView.ViewHolder{

    TextView timeView,periodView,dateView,description;
    Button transfer;

    public CardViewHolder(View v){
        super(v);

        timeView = (TextView) v.findViewById(R.id.cardTime);
        periodView = (TextView) v.findViewById(R.id.cardPeriod);
        dateView = (TextView) v.findViewById(R.id.cardDate);
        description = (TextView) v.findViewById(R.id.description);
        transfer = (Button) v.findViewById(R.id.transfer);

    }
}

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.bharath.organiserexample.MainActivity">

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/cardList">


</android.support.v7.widget.RecyclerView>

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="62dp"
    android:background="@null"
    android:src="@mipmap/add_button"
    android:layout_gravity="bottom|right"
    android:onClick="createAlarm" />


</FrameLayout>
  • what type of animation u want? you need to use itemTouchListener of recyclerview and then implement the required functionality. – Ritt Aug 15 '17 at 14:26

2 Answers2

0

Probably you should use a database, then add a swipe listener or (Gesture detector). Whenever the card is swiped you remove the current item from the card and then fetch a new item from the database or list. But I think it'll be best with something like a list, so that you can keep track of the current item. And also be able to easily remove a swiped item. When a user adds an item it is added to your list from the database. That way you don't need to worry about the position of the next item.

Joshua
  • 589
  • 1
  • 5
  • 19
  • Ya.. but I have a problem. The card is leaving the view when it is swiped, but what I want is to make the card stay there and accept the swipe and change its content. Is there any way that I can add swipe gesture to Card rather than adding it to the RecyclerView? – bharath chandra Aug 16 '17 at 08:48
  • You could use a library for swipeable cards e.g card stack or swipe cards – Joshua Aug 16 '17 at 10:08
  • I want my card to be exactly like Instagram cards with multiple photos in them. When a card with multiple photos in Instagram is swiped then the card displays the next picture. I want to make my card just like that... So what libraries should I use? – bharath chandra Aug 16 '17 at 15:36
  • check out android arsenal for card stack library – Joshua Aug 18 '17 at 09:52
0

There are a couple options. The easiest would be to have your cardview contain your description but set the visibility to GONE initially, then when the swipe event happens invert the initial state to GONE and the description to VISIBLE. I would create a helper method to do this. As far as capturing the swipe gesture, take a look at this answer.

Swipe to Dismiss for RecyclerView

You will need to be using a recyclerview but this should work if you put your invert view logic in the onSwiped method

EDIT To get the cardview, use the ViewHolder from the recyclerview

@Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
        MyCustomViewHolder vh = (MyCustomViewHolder) viewHolder;
        if(vh.isDescriptionShown()){
            vh.showDetails()
        }else {
            vh.showDescription()
        }
    }
  • Ya.. I have used ItemTouchHelper. But I don't know how to dynamically set visibility in Card. I have got this idea but gave it up coz I had no idea about it. How to set the Visibility dynamically? – bharath chandra Aug 15 '17 at 17:43
  • I have updated my answer, use the ViewHolder to access the card view. You need to implement your own ViewHolder that implements the functionality you want. Take a look at the MyAdapter class and payattention to the nested MyAdapter.ViewHolder class in the docs https://developer.android.com/training/material/lists-cards.html – Matt Goodwin Aug 15 '17 at 18:54
  • Thanks..this worked... but I have one more problem. Every time I swipe the Card is leaving the Activity. Is there any way that I can make my card stay in the activity and make my update(showing description)? – bharath chandra Aug 15 '17 at 19:22
  • can you post your code? i'm not sure what would be causing this off the top of my head – Matt Goodwin Aug 15 '17 at 21:47
  • I have added my code, and the problem is that the card goes away from the RecyclerView whenever I swipe it. Is there any way to make the card stay in the RecyclerView or can I add Swipe gesture to my Card, rather than adding it to the RecyclerView? – bharath chandra Aug 16 '17 at 08:43
  • Do you mean that the recycerview scrolls when you swipe? The size of the card is going to change when you hide and show elements inside it if the height of the card is set to wrap_content. I don't see what would cause it to leave the activity – Matt Goodwin Aug 16 '17 at 15:07