-1

This question might already be existent in StackOverflow, but I was unable to find it because I was not sure how to describe this scenario with the exact wordings, therefore I thought I should rather ask a new question and describe it here.

I have a ListView in my main activity. Each item on the ListView contains a button that is visible by default, and a textbox which is invisible by default. Once I click the button, it will be disappeared, and the textbox will be visible with a message - "Activated by currentUser". Additionally, this message will be stored in the database. This is separate from the listitem onclick event as can be noticed from my code.

Problem is, I am not being able to retain the state of the ListView items if I restart my app. Suppose, I have 4 items in my ListView. For 2 items, I have clicked only the button, and after that the button is disappeared and the textbox with "Activated by currentUser" appears. However, if I restart my app, the button appears again, and the textbox is vanished.

The app is connected to a MEAN Stack web application, so any update or delete operation will affect the main MEAN Stack application.

Here is my custom adapter code:

import com.elegantcab.getcabgo.utils.QueryUtils;

public class CabDriverNotificationAdapter extends ArrayAdapter<CabDriverNotification> {

private SessionManager mSession;
private String mNotificationId;
private String mMemo;
private static final String DATE_FORMAT = "LLL dd, yyyy";
private static final String TIME_FORMAT = "h:mm a";

public CabDriverNotificationAdapter(Context context, List<CabDriverNotification> notifications) {
    super(context, 0, notifications);

/** The static holder class will act as a holder for Android.Widget items
 * such as the activated by textview and the activate button **/
public static class ViewHolder{
    LinearLayout _layout;
    TextView _acceptedBy;
    Button acceptButton;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View listItemView = convertView;
    final ViewHolder holder;
    mSession = new SessionManager(getContext());
    final CabDriverNotification currentNotification = getItem(position);
    // get the id of current notification
    mNotificationId = String.valueOf(currentNotification.getObjectId());

    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.notification_list_item, parent, false);
        holder = new ViewHolder();
        holder._layout = (LinearLayout) listItemView.findViewById(R.id.activate_layout);  
        holder._activatedBy = (TextView) listItemView.findViewById(R.id.activated_by_message); 
        holder.activateButton = (Button) listItemView.findViewById(R.id.activate_button);  
        listItemView.setTag(holder);

        //onClickListener for activate button
        holder.activateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mMemo = toggleActivaionStatus(holder, mNotificationId);
                QueryUtils.updateNotification(getContext(), new SessionManager(getContext()).getNotificationUrl(), mNotificationId, mMemo;
            }
        });

    }

    else {
        holder = (ViewHolder) listItemView.getTag();
        holder._activatedBy = (TextView) listItemView.findViewById(R.id.activated_by_message);
        holder.activateButton = (Button) listItemView.findViewById(R.id.activate_button);
        if(currentNotification.getMemo().contains("Activated by")){
            holder._activatedBy.setText(currentNotification.getMemo());
            holder._activatedBy.setVisibility(View.VISIBLE);
            holder.activateButton.setVisibility(View.GONE);
        }
        else{
            holder._activatedBy.setVisibility(View.GONE);
            holder.activateButton.setVisibility(View.VISIBLE);
            holder.activateButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mMemo = toggleActivateStatus(holder, mNotificationId);
                    QueryUtils.updateNotification(getContext(), new SessionManager(getContext()).getNotificationUrl(), mNotificationId, mMemo);
                }
            });
        }
    }

    // Create full name from first and last name
    String fullName = currentNotification.getFirstname() + " " + currentNotification.getLastname();
    // Find the TextView with view ID name
    TextView nameView = (TextView) listItemView.findViewById(R.id.name);
    // Display the name in that TextView
    nameView.setText(fullName);

    // Create a new Date object from the time in milliseconds of the notification
    Date dateObject = new Date(currentNotification.getTimeInMilliseconds());

    // Find the TextView with view ID date
    TextView dateView = (TextView) listItemView.findViewById(R.id.date);
    // Format the date string (i.e. "Mar 3, 1984")
    final String formattedDate = formatDate(dateObject);
    // Display the date of the current notification in that TextView
    dateView.setText(formattedDate);

    // Find the TextView with view ID time
    TextView timeView = (TextView) listItemView.findViewById(R.id.time);
    // Format the time string (i.e. "4:30PM")
    final String formattedTime = formatTime(dateObject);
    // Display the time of the current notification in that TextView
    timeView.setText(formattedTime);


    // attach a listener to the list item that will display the item detail when clicked
    listItemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Context context = v.getContext();
            Intent intent = new Intent(context, NotificationDetailActivity.class);
            intent.putExtra(NotificationDetailActivity.ARG_NOTIFICATION_ID, String.valueOf(currentNotification.getObjectId()));
            intent.putExtra(NotificationDetailActivity.ARG_NOTIFICATION_DATE, formattedDate);
            intent.putExtra(NotificationDetailActivity.ARG_NOTIFICATION_TIME, formattedTime);
            context.startActivity(intent);
        }
    });


    // Return the list item view that is now showing the appropriate data
    return listItemView;
}

private String toggleActivateStatus(ViewHolder vHolder, String nid){
        HashMap<String, String> currentUser = mSession.getUserDetails();
        String user = currentUser.get("username");
        String message = "Activated by" + " " + user;
        vHolder._activatedBy.setText(message);
        vHolder._activatedBy.setVisibility(View.VISIBLE);
        vHolder.activateButton.setVisibility(View.GONE);
        return message;
    }
}

Inside onCreate of Main Activity:

 final ListView notificationListView = (ListView) findViewById(R.id.list);

 mAdapter = new CabDriverNotificationAdapter(this, new ArrayList<CabDriverNotification>());

 notificationListView.setAdapter(mAdapter);

The notification_list_item.xml:

    <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="wrap_content"
android:orientation="vertical"

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="@dimen/notification_activity_margin"
        android:layout_marginStart="@dimen/notification_activity_margin"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:fontFamily="sans-serif-medium"
            android:maxLines="1"
            android:textAllCaps="true"
            android:textColor="@color/textColorNotificationDetails"
            android:textSize="@dimen/notification_small_text_size"
            tools:text="@string/notification_item_name_default" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_margin="@dimen/notification_activity_margin"
        android:orientation="vertical">

        <TextView
            android:id="@+id/date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textColor="@color/textColorNotificationDetails"
            android:textSize="@dimen/notification_small_text_size"
            tools:text="@string/notification_detail_date_default" />

        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textColor="@color/textColorNotificationDetails"
            android:textSize="@dimen/notification_small_text_size"
            tools:text="@string/notification_detail_time_default" />

    </LinearLayout>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/accept_layout"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/activated_by_message"
        android:textColor="@color/colorPrimary"
        android:text=""
        android:visibility="invisible"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/activate_button"
        android:layout_gravity="center_horizontal"
        android:text="Activate Driver"
        android:background="@color/colorAccent"/>

</LinearLayout>

I want to retain the state of my ListView item after app restart, that said, if I have already activated two items, they should have the textbox with the message "Activated by currentUser" visible instead of the button.

1 Answers1

0

You should store data somewhere and load from this storage. For example, you can user SQLite for it. You should create table with column ACTIVATED, for example, and store in this column true or false status for your list item, and then you need to load this information for all of your list items and set visibility relying on their saved value. Or you can get values from API, for example, if you are working with web service.

EDIT:

The main idea is that you tells to application - "Please, create empty listView (or etc)", because android doesn't keep default state of your application and your views, they all will be deleted after you close the app. Even more, if you change your phone orientation, you will lose all data of your views

FIL201121
  • 114
  • 1
  • 10
  • There is a data storage, we are using MongoDB, and yes, we are getting the data through an API. Unfortunately, creating a new column is not an option for us. What we have been trying to do is: when we click the button, the message is stored in database. We are trying to see if the message contains "Activated by" string, if yes, then load the listview item with the message textbox and hide the button, if no, then load the item with button and hide the textbox. – Choudhury Saadmaan Mahmid May 30 '18 at 19:09
  • So, you are put in storage position of list item, or what? Because you need to parse response from server or load data from database in the form like _user_ _isClicked_ or _user_ _listItemPosition_, for example. Idea is that you need to give information for app and listView about users actions. If you are already use database in the same way as I wrote, check your database values and your ArrayList values – FIL201121 May 30 '18 at 19:27