0

I've searched for it everywhere but I didn't found a satisfying answer yet. So, I'd would like to know: How to show an activity as a popup/dialog when clicking on a card from a recyclerview? Is it made straight through the adapter? Do I need a second activity to do that or just another layout.xml is enough?

I've tried:

android:theme="@style/Theme.AppCompat.Dialog"

But it's throwing the following error everytime I click on the card from the recyclerview:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.softdevandre.marvelapi/com.softdevandre.marvelapi.ui.DetailCharacterActivity}: android.view.InflateException: Binary XML file line #11 in com.softdevandre.marvelapi:layout/activity_detail_character: Binary XML file line #11 in com.softdevandre.marvelapi:layout/activity_detail_character: Error inflating class <unknown>

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.softdevandre.marvelapi" >

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MarvelAPI"
        tools:targetApi="31" >
        <activity
            android:name=".ui.DetailCharacterActivity"
            android:theme="@style/Theme.AppCompat.Dialog"
            android:autoRemoveFromRecents="true"
            android:parentActivityName=".MainActivity"
            android:exported="false" >
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity
            android:name=".MainActivity"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_detail_character.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="255dp"
    android:layout_margin="8dp"
    app:cardElevation="5dp"
    app:cardCornerRadius="8dp"
    tools:context=".ui.DetailCharacterActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/ivCharacter"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="ImageContrastCheck"
            tools:srcCompat="@tools:sample/avatars" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="#80CC0000"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/tvCharacterName"
                android:layout_width="match_parent"
                android:textColor="@color/white"
                android:gravity="center"
                android:layout_height="match_parent"
                android:layout_marginStart="12dp"
                android:layout_marginBottom="12dp"
                android:layout_marginEnd="12dp"
                android:layout_marginTop="8dp"
                android:textSize="16sp"
                android:textStyle="bold"
                tools:text="Character Name" />

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>

ItemCharacterAdapter.kt:

class ItemCharacterAdapter(private val context: Context, private val dataset: List<Characters>) :
    RecyclerView.Adapter<ItemCharacterAdapter.CharacterViewHolder>() {

    class CharacterViewHolder(binding: ItemCharacterBinding) :
        RecyclerView.ViewHolder(binding.root) {
        val textView: TextView = binding.tvCharacterName
        val imageView: ImageView = binding.ivCharacter
        val materialCard: MaterialCardView = binding.mcvCharacter
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CharacterViewHolder {
        // create new view
        val adapterLayout =
            ItemCharacterBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return CharacterViewHolder(adapterLayout)
    }

    override fun onBindViewHolder(holder: CharacterViewHolder, position: Int) {
        val item = dataset[position]
        holder.textView.text = context.resources.getString(item.name)
        holder.imageView.setImageResource(item.image)
        holder.materialCard.setOnClickListener {
            val intent = Intent(context, DetailCharacterActivity::class.java)
            context.startActivity(intent)
        }
    }

    override fun getItemCount() = dataset.size
}

MainActivity.kt:

class MainActivity : AppCompatActivity() {

    private val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        val myDataset = Datasource().loadCharacters()

        val recyclerView = binding.rvCharacterList
        recyclerView.adapter = ItemCharacterAdapter(this, myDataset)

    }
}

Thanks in advance.

devAndre
  • 1
  • 5

1 Answers1

0

To start activity as dialog defined it like this in AndroidManifest.xml:

<activity android:theme="@android:style/Theme.Dialog" />

Use this property inside your activity tag to avoid that your Dialog appears in the recently used apps list

android:excludeFromRecents="true"

If you want to stop your dialog / activity from being destroyed when the user clicks outside of the dialog:

After setContentView() in your Activity use:

this.setFinishOnTouchOutside(false);

Now, call startActivity() on your recycler view card click it displays as a dialog, with the previous activity shown when the user presses the back button.

Note that if you are using ActionBarActivity (or AppCompat theme), you'll need to use @style/Theme.AppCompat.Dialog instead.

Khush Parmar
  • 316
  • 2
  • 9
  • I've tried this approach already and it keeps throwing the error (InflateException) I've pointed out above. And I haven't found a solution for this exception as well. – devAndre Oct 07 '22 at 13:48
  • This exception means you inflated a wrong layout file. Must check the inflated layouts are correct with your used binding inflation functionality and must do clean and build cause sometimes binding also throws this errors if there’s any change. – Khush Parmar Oct 09 '22 at 11:51