Home > Blockchain >  Cardview shows twice when dynamically generated
Cardview shows twice when dynamically generated

Time:03-18

I'm trying to create a list of cards that will be generated dynamically because there is some stuff in the card that I need to pull from FireStore. I got it pretty much done but the card shows up sort of twice, the actual card shows up fine but then there is like the card layout in the back with the preset texts and stuff

Update: after some suggestions and help I changed the code, it still doesn't do what I want but I guess its a step in the right direction

here's the code I use to create the card (updated with full activity)

public class ScrollingActivity extends AppCompatActivity {

FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseAuth fAuth = FirebaseAuth.getInstance();
LinearLayout layout;
String name;

float rating;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_scrolling);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    CollapsingToolbarLayout toolBarLayout = findViewById(R.id.toolbar_layout);
    toolBarLayout.setTitle(getTitle());

    for (int i = 0; i<6; i  ){
        addCard(i);
    }

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
            .setAction("Action", null).show());

}

private void addCard(int workerNum) {
    layout = findViewById(R.id.thisone);
    View card = getLayoutInflater().inflate(R.layout.sample_card_1, layout, false);

    TextView nameWorker = findViewById(R.id.nameWorker);
    RatingBar RatingBar = findViewById(R.id.ratingBar);
    Button submitButton = findViewById(R.id.submitButton);

    DocumentReference docRef = db.collection("workers").document(String.valueOf(workerNum));
    docRef.get().addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            if (document.exists()) {
                Log.d(TAG, "DocumentSnapshot data: "   document.getData());
                name = document.toObject(Classes.Worker.class).getName();
                nameWorker.setText(name);
                rating = document.toObject(Classes.Worker.class).getRating();
                RatingBar.setRating(rating);
            } else {
                Log.d(TAG, "No such document");
            }
        } else {
            Log.d(TAG, "get failed with ", task.getException());
        }
    });

    // perform click event on button
    submitButton.setOnClickListener(v -> {
        DocumentReference changerating = db.collection("workers").document(String.valueOf(workerNum));
        changerating.update("rating", RatingBar.getRating()).addOnSuccessListener(aVoid ->
                Log.d(TAG, "DocumentSnapshot successfully updated!"))
                .addOnFailureListener(e -> Log.w(TAG, "Error updating document", e));
        // get values and then displayed in a toast
        String rating1 = "On a scale of 5 Stars\n New rating = "   RatingBar.getRating();
        Toast.makeText(getApplicationContext(), rating1, Toast.LENGTH_LONG).show();
    });

    layout.addView(card);
}

Here's the xml of the layout where the cards are actually shown

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ScrollingActivity">

<com.google.android.material.appbar.AppBarLayout
    android:id="@ id/app_bar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/app_bar_height"
    android:fitsSystemWindows="true"
    android:theme="@style/Theme.InternshipThesis.AppBarOverlay">

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@ id/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:toolbarId="@ id/toolbar">

        <androidx.appcompat.widget.Toolbar
            android:id="@ id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/Theme.InternshipThesis.PopupOverlay" />

    </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".ScrollingActivity"
    tools:showIn="@layout/activity_scrolling">


    <LinearLayout
        android:id="@ id/thisone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="20dp">

        <include layout="@layout/sample_card_1" />
    </LinearLayout>

</androidx.core.widget.NestedScrollView>

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@ id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    app:layout_anchor="@id/app_bar"
    app:layout_anchorGravity="bottom|end"
    app:srcCompat="@android:drawable/ic_menu_sort_by_size"
    android:contentDescription="@string/main_fab_desc" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Here's the layout of the card

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@ id/card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="20dp"
app:cardElevation="2dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp">

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@ id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="15dp">

    <com.google.android.material.imageview.ShapeableImageView
        android:id="@ id/imageView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:shapeAppearanceOverlay="@style/roundedImageView"
        android:contentDescription="@string/Desc_Photo_Card1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/sample_worker_1" />

    <TextView
        android:id="@ id/nameWorker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/Text1_Card1"
        android:textSize="20sp"
        app:layout_constraintStart_toEndOf="@ id/imageView"
        app:layout_constraintTop_toTopOf="@ id/imageView"
        android:padding="10dp"/>

    <RatingBar
        android:id="@ id/ratingBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@ id/imageView"
        app:layout_constraintStart_toEndOf="@ id/imageView"
        app:layout_constraintTop_toBottomOf="@ id/nameWorker" />

    <com.google.android.material.button.MaterialButton
        android:id="@ id/submitButton"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="10dp"
        android:text="@string/rating_button"
        android:textColor="#fff"
        android:textSize="20sp"
        android:textStyle="bold"
        app:cornerRadius="20dp"
        app:layout_constraintEnd_toEndOf="@ id/ratingBar"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@ id/ratingBar"
        app:layout_constraintTop_toBottomOf="@ id/ratingBar" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

here's how it currently shows in the app

example 1

If I dont include the layout of the card in the xml of the activity, the app crashes because it cant find the objects inside the cards to fill in with data, but if I include it apparently it creates one card correctly filled and all the other ones are just filled with the preset data

CodePudding user response:

The issue you're having is based in your AddCard function. You're inflating the card_view, but then instead of looking inside the new card_view (the variable card) for the views to fill with data, you're looking inside the root view (if you just call findViewById, it will look inside the root view of the fragment/activity by default).

To remedy this:

  1. Remove this line from your main view: <include layout="@layout/sample_card_1" />, as it's not necessary (your code should dynamically add the cards)
  2. Modify your AddCard function, and change these three lines as below:
    TextView nameWorker = card.findViewById(R.id.nameWorker);
    RatingBar RatingBar = card.findViewById(R.id.ratingBar);
    Button submitButton = card.findViewById(R.id.submitButton);

By changing the findViewById calls to instead call on the card view you've inflated, you'll stop looking inside the root view (which will solve those crashes you referenced), and instead will fill out the new card with the details you want (which will solve the issue you're having of one card being filled out and the rest being default values).

CodePudding user response:

the thing you missed is you should have added cardview_layout into LinearLayout Vertical, not into CardView on your activity.xml. so wrap the card_layout.xml with CardView like you did in main.xml(it should be top element instead of ConstraintLayout on your card_layout.xml) and remove below code from main_activity.xml

<androidx.cardview.widget.CardView
        android:id="@ id/cardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        app:cardCornerRadius="20dp"
        app:cardElevation="2dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@ id/textView2">

        <include
            layout="@layout/sample_card_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </androidx.cardview.widget.CardView>

after you remove, add LinearLayout instead with vertical orientation. then add the cardview_layout programmatically into the LinearLayout you have already added.

and use view instead of directly calling findviewbyıd to prevent crash like below:

    TextView nameWorker = view.findViewByID()
  • Related