Skip to content
Snippets Groups Projects
Commit 7ec96481 authored by Julian Catoni's avatar Julian Catoni
Browse files

Added widgets to recognition view, added past recognitions

parent d6961cb4
Branches
No related tags found
No related merge requests found
package org.openhab.habdroid.ui;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import org.openhab.habdroid.R;
import org.openhab.habdroid.model.ChangedItem;
import org.openhab.habdroid.model.Item;
import org.openhab.habdroid.model.Recognition;
import org.openhab.habdroid.model.Widget;
import java.text.DateFormat;
import java.util.List;
public class ChangedItemsAdapter extends RecyclerView.Adapter<ChangedItemsAdapter.CustomViewHolder> {
private List<ChangedItem> mChangedItems;
private Context mContext;
private static final int TYPE_GENERICITEM = 0;
private static final int TYPE_FRAME = 1;
private static final int TYPE_GROUP = 2;
private static final int TYPE_SWITCH = 3;
private static final int TYPE_TEXT = 4;
private static final int TYPE_SLIDER = 5;
private static final int TYPE_IMAGE = 6;
private static final int TYPE_SELECTION = 7;
private static final int TYPE_SECTIONSWITCH = 8;
private static final int TYPE_ROLLERSHUTTER = 9;
private static final int TYPE_SETPOINT = 10;
private static final int TYPE_CHART = 11;
private static final int TYPE_VIDEO = 12;
private static final int TYPE_WEB = 13;
private static final int TYPE_COLOR = 14;
private static final int TYPE_VIDEO_MJPEG = 15;
private static final int TYPE_LOCATION = 16;
public ChangedItemsAdapter(Context context, List<ChangedItem> changedItems){
mContext = context;
mChangedItems = changedItems;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
public final View mView;
TextView recDescription;
TextView recType;
TextView recActivity;
TextView recTimestamp;
TextView recChangedState;
CustomViewHolder(View itemView) {
super(itemView);
mView = itemView;
recDescription = mView.findViewById(R.id.recognitionDescription);
recType = mView.findViewById(R.id.recognitionType);
recActivity = mView.findViewById(R.id.recognitionActivity);
recTimestamp = mView.findViewById(R.id.recognitionTimestamp);
recChangedState = mView.findViewById(R.id.recognitionChangedState);
}
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.custom_row, parent, false);
return new CustomViewHolder(view);
}
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
ChangedItem item = mChangedItems.get(position);
}
@Override
public int getItemCount() {
return mChangedItems == null ? 0 : mChangedItems.size();
}
@Override
public int getItemViewType(int position) {
return getItemViewType(mChangedItems.get(position));
}
private int getItemViewType(ChangedItem changedItem) {
switch (changedItem.getType()) {
case ColorLamp:
return TYPE_COLOR;
case DimmableLamp:
return TYPE_SLIDER;
default:
throw new IllegalArgumentException("ChangedItem type " + changedItem.getType() + " is not known");
}
}
}
...@@ -79,6 +79,7 @@ import org.openhab.habdroid.core.connection.exception.NoUrlInformationException; ...@@ -79,6 +79,7 @@ import org.openhab.habdroid.core.connection.exception.NoUrlInformationException;
import org.openhab.habdroid.model.LinkedPage; import org.openhab.habdroid.model.LinkedPage;
import org.openhab.habdroid.model.ServerProperties; import org.openhab.habdroid.model.ServerProperties;
import org.openhab.habdroid.model.Sitemap; import org.openhab.habdroid.model.Sitemap;
import org.openhab.habdroid.model.Widget;
import org.openhab.habdroid.ui.activity.ContentController; import org.openhab.habdroid.ui.activity.ContentController;
import org.openhab.habdroid.util.AsyncHttpClient; import org.openhab.habdroid.util.AsyncHttpClient;
import org.openhab.habdroid.util.AsyncServiceResolver; import org.openhab.habdroid.util.AsyncServiceResolver;
...@@ -94,6 +95,7 @@ import java.security.cert.CertPathValidatorException; ...@@ -94,6 +95,7 @@ import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateRevokedException; import java.security.cert.CertificateRevokedException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -140,6 +142,8 @@ public class MainActivity extends AppCompatActivity implements ...@@ -140,6 +142,8 @@ public class MainActivity extends AppCompatActivity implements
private ServerProperties.UpdateHandle mPropsUpdateHandle; private ServerProperties.UpdateHandle mPropsUpdateHandle;
private boolean mStarted; private boolean mStarted;
private ArrayList<Widget> mWidgets = new ArrayList<>();
/** /**
* Daydreaming gets us into a funk when in fullscreen, this allows us to * Daydreaming gets us into a funk when in fullscreen, this allows us to
* reset ourselves to fullscreen. * reset ourselves to fullscreen.
...@@ -255,6 +259,11 @@ public class MainActivity extends AppCompatActivity implements ...@@ -255,6 +259,11 @@ public class MainActivity extends AppCompatActivity implements
prefsEditor.apply(); prefsEditor.apply();
} }
public void updateWidgets(List<Widget> widgets) {
mWidgets.clear();
mWidgets.addAll(widgets);
}
private void handleConnectionChange() { private void handleConnectionChange() {
if (mConnection instanceof DemoConnection) { if (mConnection instanceof DemoConnection) {
showSnackbar(R.string.info_demo_mode_short); showSnackbar(R.string.info_demo_mode_short);
...@@ -568,6 +577,7 @@ public class MainActivity extends AppCompatActivity implements ...@@ -568,6 +577,7 @@ public class MainActivity extends AppCompatActivity implements
return true; return true;
case R.id.recognitions: case R.id.recognitions:
openRecognitions(); openRecognitions();
return true; return true;
default: default:
break; break;
...@@ -690,7 +700,7 @@ public class MainActivity extends AppCompatActivity implements ...@@ -690,7 +700,7 @@ public class MainActivity extends AppCompatActivity implements
private void openRecognitions() { private void openRecognitions() {
Intent recognitionsIntent = new Intent(this, RecognitionsActivity.class); Intent recognitionsIntent = new Intent(this, RecognitionsActivity.class);
recognitionsIntent.putExtra("serverProperties", mServerProperties); recognitionsIntent.putExtra("serverProperties", mServerProperties);
recognitionsIntent.putParcelableArrayListExtra("widgets", mWidgets);
startActivityForResult(recognitionsIntent, INFO_REQUEST_CODE); startActivityForResult(recognitionsIntent, INFO_REQUEST_CODE);
Util.overridePendingTransition(this, false); Util.overridePendingTransition(this, false);
} }
......
...@@ -2,16 +2,23 @@ package org.openhab.habdroid.ui; ...@@ -2,16 +2,23 @@ package org.openhab.habdroid.ui;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
import org.openhab.habdroid.R; import org.openhab.habdroid.R;
import org.openhab.habdroid.core.connection.Connection;
import org.openhab.habdroid.core.connection.ConnectionFactory;
import org.openhab.habdroid.core.connection.exception.ConnectionException;
import org.openhab.habdroid.model.ChangedItem;
import org.openhab.habdroid.model.Recognition; import org.openhab.habdroid.model.Recognition;
import org.openhab.habdroid.model.Widget;
import org.openhab.habdroid.util.Util; import org.openhab.habdroid.util.Util;
import org.openhab.habdroid.util.GetDataService; import org.openhab.habdroid.util.GetDataService;
import org.openhab.habdroid.util.RetrofitClientInstance; import org.openhab.habdroid.util.RetrofitClientInstance;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -37,12 +44,8 @@ import android.widget.Toast; ...@@ -37,12 +44,8 @@ import android.widget.Toast;
public class RecognitionsActivity extends AppCompatActivity{ public class RecognitionsActivity extends AppCompatActivity{
private RecognitionsAdapter adapter; private RecognitionsAdapter mPastRecognitionsAdapter;
private RecyclerView recyclerView; private RecyclerView mRvPastRecognitions;
private TextView mCurrentActivityTitle;
private TextView mCurrentActivityTime;
private RecyclerView mCurrentActivityChangedItems;
private ChangedItemsAdapter mChangedItemsAdapter;
ProgressDialog progressDialog; ProgressDialog progressDialog;
...@@ -83,7 +86,7 @@ public class RecognitionsActivity extends AppCompatActivity{ ...@@ -83,7 +86,7 @@ public class RecognitionsActivity extends AppCompatActivity{
progressDialog.dismiss(); progressDialog.dismiss();
//generateDataList(response.body()); //generateDataList(response.body());
generateCurrentActivity(response.body().get(0)); generateCurrentActivity(response.body().get(0));
generatePastActivities(response.body().subList(1, response.body().size()));
} }
@Override @Override
...@@ -96,16 +99,47 @@ public class RecognitionsActivity extends AppCompatActivity{ ...@@ -96,16 +99,47 @@ public class RecognitionsActivity extends AppCompatActivity{
} }
private void generateCurrentActivity(Recognition recognition) { private void generateCurrentActivity(Recognition recognition) {
mCurrentActivityTitle = findViewById(R.id.text_recognition_current_title); TextView mCurrentActivityTitle = findViewById(R.id.text_recognition_current_title);
mCurrentActivityTime = findViewById(R.id.text_recognition_current_time); TextView mCurrentActivityTime = findViewById(R.id.text_recognition_current_time);
mCurrentActivityChangedItems = findViewById(R.id.rv_recognition_current_items); RecyclerView mCurrentActivityChangedItems = findViewById(R.id.rv_recognition_current_items);
mCurrentActivityTitle.setText(recognition.getDescription().toString()); mCurrentActivityTitle.setText(recognition.getDescription().toString());
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.US); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.US);
mCurrentActivityTime.setText(dateFormat.format(new Date(recognition.getTimestamp()))); mCurrentActivityTime.setText(dateFormat.format(new Date(recognition.getTimestamp())));
mChangedItemsAdapter = new ChangedItemsAdapter(this.getApplicationContext(), recognition.getChangedItems()); ArrayList<Widget> widgets = getIntent().getParcelableArrayListExtra("widgets");
ArrayList<Widget> activityWidgets = new ArrayList<>();
for (ChangedItem ci : recognition.getChangedItems()) {
for (Widget widget : widgets) {
if (widget.item() != null && ci.getName().equals(widget.item().name())) {
activityWidgets.add(widget);
}
}
}
try {
Connection c = ConnectionFactory.getUsableConnection();
if (c != null) {
WidgetAdapter mChangedItemsAdapter = new WidgetAdapter(this, c, null);
mChangedItemsAdapter.update(activityWidgets, false);
mCurrentActivityChangedItems.setLayoutManager(new LinearLayoutManager(this)); mCurrentActivityChangedItems.setLayoutManager(new LinearLayoutManager(this));
mCurrentActivityChangedItems.setAdapter(mChangedItemsAdapter); mCurrentActivityChangedItems.setAdapter(mChangedItemsAdapter);
} }
} catch (ConnectionException e) {
Toast.makeText(this, "No connection", Toast.LENGTH_LONG).show();
}
}
private void generatePastActivities(List<Recognition> recognitions) {
ArrayList<Recognition> filteredRecognitions = new ArrayList<>();
for (Recognition r : recognitions) {
if (r.getType().equals("recognition")) {
filteredRecognitions.add(r);
}
}
mRvPastRecognitions = findViewById(R.id.rv_past_recognitions);
mPastRecognitionsAdapter = new RecognitionsAdapter(this, filteredRecognitions);
mRvPastRecognitions.setLayoutManager(new LinearLayoutManager(this));
mRvPastRecognitions.setAdapter(mPastRecognitionsAdapter);
}
/* /*
// Generates a List using RecyclerView with the RecognitionsAdapter // Generates a List using RecyclerView with the RecognitionsAdapter
......
...@@ -7,10 +7,13 @@ import android.view.ViewGroup; ...@@ -7,10 +7,13 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.openhab.habdroid.R; import org.openhab.habdroid.R;
import org.openhab.habdroid.model.ChangedItem;
import org.openhab.habdroid.model.Recognition; import org.openhab.habdroid.model.Recognition;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
...@@ -22,35 +25,27 @@ import androidx.recyclerview.widget.RecyclerView; ...@@ -22,35 +25,27 @@ import androidx.recyclerview.widget.RecyclerView;
public class RecognitionsAdapter extends RecyclerView.Adapter<RecognitionsAdapter.CustomViewHolder> { public class RecognitionsAdapter extends RecyclerView.Adapter<RecognitionsAdapter.CustomViewHolder> {
private List<Recognition> dataList; private List<Recognition> mRecognitions;
private Context context; private Context mContext;
public RecognitionsAdapter(Context context, List<Recognition> dataList/*, List<ChangedItem> changedItemList*/){ public RecognitionsAdapter(Context context, List<Recognition> recognitions){
this.context = context; this.mContext = context;
this.dataList = dataList; this.mRecognitions = recognitions;
} }
class CustomViewHolder extends RecyclerView.ViewHolder { class CustomViewHolder extends RecyclerView.ViewHolder {
public final View mView; final View mView;
TextView recDescription; TextView recognitionTitle;
TextView recType; TextView recognitionTime;
TextView recActivity;
TextView recTimestamp;
TextView recChangedState;
CustomViewHolder(View itemView) { CustomViewHolder(View itemView) {
super(itemView); super(itemView);
mView = itemView; mView = itemView;
recognitionTime = itemView.findViewById(R.id.text_recognition_past_time);
recDescription = mView.findViewById(R.id.recognitionDescription); recognitionTitle = itemView.findViewById(R.id.text_recognition_past_title);
recType = mView.findViewById(R.id.recognitionType);
recActivity = mView.findViewById(R.id.recognitionActivity);
recTimestamp = mView.findViewById(R.id.recognitionTimestamp);
recChangedState = mView.findViewById(R.id.recognitionChangedState);
} }
} }
...@@ -58,52 +53,20 @@ public class RecognitionsAdapter extends RecyclerView.Adapter<RecognitionsAdapte ...@@ -58,52 +53,20 @@ public class RecognitionsAdapter extends RecyclerView.Adapter<RecognitionsAdapte
@Override @Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.custom_row, parent, false); View view = layoutInflater.inflate(R.layout.list_item_past_recognition, parent, false);
return new CustomViewHolder(view); return new CustomViewHolder(view);
} }
@Override @Override
public void onBindViewHolder(CustomViewHolder holder, int position) { public void onBindViewHolder(CustomViewHolder holder, int position) {
int identifier = dataList.get(position).getIdentifier(); Recognition item = mRecognitions.get(position);
String type = dataList.get(position).getType(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.US);
Object activity = dataList.get(position).getActivity(); holder.recognitionTime.setText(dateFormat.format(new Date(item.getTimestamp())));
Object description = dataList.get(position).getDescription(); holder.recognitionTitle.setText(item.getDescription().toString());
int timestamp = dataList.get(position).getTimestamp();
// ChangedItem
String name;
String state;
String label;
// String changedItem = String.join(",", name, state, label);
// if (dataList.get(position).getChangedItems().size() == 3) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataList.get(position).getChangedItems().size(); i++) {
name = dataList.get(position).getChangedItems().get(i).getName();
state = dataList.get(position).getChangedItems().get(i).getState();
label = dataList.get(position).getChangedItems().get(i).getLabel();
String changedItem = String.join(",", name, state, label);
// changedStates.add(changedItem);
sb.append(changedItem).append('\n');
// Uncomment line 104 and comment out line 114 and 115 to see the alternate behavior
// holder.recChangedState1.setText(changedItem);
}
holder.recDescription.setText((CharSequence) description);
holder.recType.setText(type);
holder.recActivity.setText((CharSequence) activity);
holder.recTimestamp.setText(DateFormat.getDateTimeInstance().format(timestamp));
holder.recChangedState.setText(sb.toString());
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return dataList == null ? 0 : dataList.size(); return mRecognitions == null ? 0 : mRecognitions.size();
} }
} }
...@@ -31,6 +31,7 @@ import org.openhab.habdroid.model.Widget; ...@@ -31,6 +31,7 @@ import org.openhab.habdroid.model.Widget;
import org.openhab.habdroid.util.CacheManager; import org.openhab.habdroid.util.CacheManager;
import org.openhab.habdroid.util.Util; import org.openhab.habdroid.util.Util;
import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -80,7 +81,7 @@ public class WidgetListFragment extends Fragment ...@@ -80,7 +81,7 @@ public class WidgetListFragment extends Fragment
Log.d(TAG, "onActivityCreated()"); Log.d(TAG, "onActivityCreated()");
Log.d(TAG, "isAdded = " + isAdded()); Log.d(TAG, "isAdded = " + isAdded());
mActivity = (MainActivity) getActivity(); mActivity = (MainActivity) getActivity();
mActivity.updateWidgets(mWidgets);
mAdapter = new WidgetAdapter(mActivity, mActivity.getConnection(), this); mAdapter = new WidgetAdapter(mActivity, mActivity.getConnection(), this);
mLayoutManager = new LinearLayoutManager(mActivity); mLayoutManager = new LinearLayoutManager(mActivity);
...@@ -251,9 +252,10 @@ public class WidgetListFragment extends Fragment ...@@ -251,9 +252,10 @@ public class WidgetListFragment extends Fragment
mAdapter.setSelectedPosition(-1); mAdapter.setSelectedPosition(-1);
} }
public ArrayList<Widget> mWidgets = new ArrayList<>();
public void update(String pageTitle, List<Widget> widgets) { public void update(String pageTitle, List<Widget> widgets) {
mTitle = pageTitle; mTitle = pageTitle;
mWidgets.addAll(widgets);
if (mAdapter != null) { if (mAdapter != null) {
mAdapter.update(widgets, mRefreshLayout.isRefreshing()); mAdapter.update(widgets, mRefreshLayout.isRefreshing());
setHighlightedPageLink(mHighlightedPageLink); setHighlightedPageLink(mHighlightedPageLink);
...@@ -261,6 +263,7 @@ public class WidgetListFragment extends Fragment ...@@ -261,6 +263,7 @@ public class WidgetListFragment extends Fragment
} }
if (mActivity != null && mIsVisible) { if (mActivity != null && mIsVisible) {
mActivity.updateTitle(); mActivity.updateTitle();
mActivity.updateWidgets(widgets);
} }
} }
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Layout for OpenLicht Recognition--><!--By Muhammad Ibrahim Rahman-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -13,38 +10,8 @@ ...@@ -13,38 +10,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:elevation="8dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<!--
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:activatedBackgroundIndicator"
android:descendantFocusability="blocksDescendants">
<include layout="@layout/widgetlist_icontext" />
<ImageButton
style="@style/ActionButton"
android:id="@+id/up_button"
android:contentDescription="@string/content_description_color_up"
android:src="?themedArrowUpIcon" />
<ImageButton
style="@style/ActionButton"
android:id="@+id/select_color_button"
android:contentDescription="@string/content_description_open_color_wheel"
android:src="?themedColorIcon" />
<ImageButton
style="@style/ActionButton"
android:id="@+id/down_button"
android:contentDescription="@string/content_description_color_down"
android:src="?themedArrowDownIcon" />
</LinearLayout>
-->
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/card_recognition_current" android:id="@+id/card_recognition_current"
...@@ -89,9 +56,21 @@ ...@@ -89,9 +56,21 @@
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
<!--
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Past activities"
android:textAllCaps="true"
android:textColor="@color/black"
android:layout_marginTop="16dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:textSize="10dp"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/customRecyclerView" android:id="@+id/rv_past_recognitions"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" />--> android:layout_height="match_parent" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Widget.MaterialComponents.CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/mtrl_card_spacing"
android:layout_marginTop="@dimen/mtrl_card_spacing"
android:layout_marginRight="@dimen/mtrl_card_spacing">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/text_recognition_past_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="18sp" />
<TextView
android:id="@+id/text_recognition_past_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment