如何在 Kotlin 中显示来自 RecyclerView 的全屏图像?

Posted

技术标签:

【中文标题】如何在 Kotlin 中显示来自 RecyclerView 的全屏图像?【英文标题】:How to display Fullscreen image from RecyclerView in Kotlin? 【发布时间】:2021-09-15 00:13:15 【问题描述】:

我从 API 获取数据并将其显示在 RecyclerView 中,一切正常

但现在我有点困惑,如果用户点击它,我如何全屏显示我从 API 获取的图像

这是活动:

LlmNoteDetailsActivity:

class LlmNoteDetailsActivity : AppCompatActivity() 
override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.fragment_ilm_note_detail)


    val EventName = intent.getStringExtra("EventName")
    val EventLink = intent.getStringExtra("EventLink")
    val isFavourite = intent.getBooleanExtra("isFavourite" , false)
    val eventId = intent.getIntExtra("eventId",0)
    val eventDate = intent.getStringExtra("eventDate")
    val eventDescription = intent.getStringExtra("eventDescription")
    val eventLocation = intent.getStringExtra("eventLocation")
    val eventLink = intent.getStringExtra("eventLink")
    val EventImage = intent.getStringExtra("EventImage")


    val ImageViewTop: ImageView = findViewById(R.id.ImageViewTop)
    val LinkText: TextView = findViewById(R.id.LocationTx)
    val EventNameText: TextView = findViewById(R.id.EventNameText)
    val eventDateTxt: TextView = findViewById(R.id.eventDateTxt)
    val eventDescriptionText: TextView = findViewById(R.id.eventDescriptionText)
    val butttoRegiiste: Button = findViewById(R.id.butttoRegiiste)
    val detailback_btn: ImageButton = findViewById(R.id.detailback_btn)


    LinkText.text = EventLink
    EventNameText.text = EventName
    eventDateTxt.text = eventDate
    eventDescriptionText.text = eventDescription

    butttoRegiiste.setOnClickListener 

        openLinkInBrowser(eventLink!!)
    

    detailback_btn.setOnClickListener 

        onBackPressed()
    

    ImageViewTop.setOnClickListener 
        //display image in fullscreen
    


    Picasso.get()
        .load(EventImage)
        .error(R.drawable.qiblacompass)
        .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
        .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
        .into(ImageViewTop)










fun openLinkInBrowser(url: String) 


    try 
        val url = if (Uri.parse(url).scheme == null || !url.startsWith("https://") && !url.startsWith(
                "http://"
            )) 
            "https://$url"
         else url
        val webPage: Uri = Uri.parse(url)

        val intent = Intent(Intent.ACTION_VIEW, webPage)

        this.startActivity(intent)


     catch (e: Exception) 
        e.printStackTrace()
    


这是它的布局(fragment_ilm_note_detail):

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    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_
    android:layout_>

    <RelativeLayout
        android:layout_
        android:layout_>


        <ImageView
            android:layout_marginTop="-100dp"
            android:id="@+id/ImageViewTop"
            android:layout_
            android:layout_
            android:contentDescription="login background"
            android:src="@drawable/sampledetail" />





        <com.google.android.flexbox.FlexboxLayout
            android:layout_
            android:layout_
            android:layout_marginTop="350dp"
            android:layout_alignParentBottom="true"
            android:orientation="vertical"
            app:flexDirection="column">
            <LinearLayout
                android:background="@drawable/rounded_background"
                android:layout_
                android:layout_
                android:paddingTop="@dimen/dimen_16"
                android:paddingLeft="@dimen/dimen_16"
                android:paddingRight="@dimen/dimen_16"
                android:elevation="5dp">
                <LinearLayout
                    android:layout_
                    android:layout_
                    android:layout_gravity="center"
                    android:orientation="vertical"
                    android:padding="20dp">

                    <com.google.android.flexbox.FlexboxLayout
                        android:layout_
                        app:justifyContent="space_between"
                        android:layout_>
                        <com.google.android.flexbox.FlexboxLayout
                            app:alignItems="center"
                            android:layout_
                            android:layout_>
                            <ImageView
                                android:layout_marginRight="10dp"
                                android:src="@drawable/pin"
                                android:layout_
                                android:layout_/>
                            <TextView
                                android:id="@+id/LocationTx"
                                android:layout_
                                android:layout_
                                android:fontFamily="@font/poppins"
                                android:text="Ara Damansara"
                                android:textColor="@color/black"
                                android:textSize="15sp" />
                        </com.google.android.flexbox.FlexboxLayout>
                        <ImageView
                            android:layout_marginRight="10dp"
                            android:src="@drawable/star"
                            android:layout_
                            android:layout_/>
                    </com.google.android.flexbox.FlexboxLayout>

                    <TextView
                        android:id="@+id/EventNameText"
                        android:layout_
                        android:layout_
                        android:layout_marginTop="20dp"
                        android:fontFamily="@font/poppins"
                        android:text="Perfecting My Solah"
                        android:textColor="@color/teal_600"
                        android:textSize="20sp"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/eventDateTxt"
                        android:layout_
                        android:layout_
                        android:layout_marginTop="3dp"
                        android:fontFamily="@font/poppins_semibold"
                        android:text="Sabtu 15 Ogos 2021"
                        android:textColor="@color/black"
                        android:textSize="15sp"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/eventDescriptionText"
                        android:layout_
                        android:layout_
                        android:layout_marginTop="15dp"

                        android:fontFamily="@font/poppins"
                        android:text=""
                        android:textColor="@color/black"
                        android:textSize="10sp" />

                    <Button
                        android:id="@+id/butttoRegiiste"
                        android:layout_
                        android:layout_
                        android:layout_gravity="center"
                        android:layout_marginVertical="@dimen/dimen_32"
                        android:backgroundTint="#FFB248"
                        android:textAllCaps="false"
                        android:text="Link to Register"
                        app:rippleColor="#FFB248" />

                </LinearLayout>
            </LinearLayout>


        </com.google.android.flexbox.FlexboxLayout>

        <ImageButton
            android:id="@+id/detailback_btn"
            android:layout_
            android:layout_marginLeft="@dimen/_20sdp"
            android:layout_marginTop="@dimen/_50sdp"
            android:layout_
            android:background="@drawable/chevron_left" />
    </RelativeLayout>

</ScrollView>

这是适配器:

IimfinderAdapter:

class IimfinderAdapter(var countryList: List<ilmFinders>, private val iimfinderAdapterCallback: MainActivity): RecyclerView.Adapter<IimfinderAdapter.ViewHolder>()
lateinit var context: Context
val CategoryID: Int = AppPreferences.heightInCentimeters ?: 170
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IimfinderAdapter.ViewHolder 
    context = parent.context!!
    val view = LayoutInflater.from(context).inflate(R.layout.list_item2, parent, false)
    return ViewHolder(view)


override fun getItemCount(): Int 
    return countryList[CategoryID].ilmFinders.size


override fun onBindViewHolder(holder: IimfinderAdapter.ViewHolder, position: Int) 

    var categoryIDis = countryList[CategoryID].categoryID

    Log.e("CategoryID",categoryIDis.toString())
    Log.e("Categorycount ",countryList[CategoryID].ilmFinders.size.toString())




    holder.eventName.text = countryList[CategoryID].ilmFinders[position].eventName
    holder.eventLink.text = countryList[CategoryID].ilmFinders[position].eventLink
    Log.d("ggggggggggggggg", countryList[CategoryID].ilmFinders[position].eventName)



   var ilmfinderimage =  countryList[CategoryID].ilmFinders[position].eventPhoto.toString()

  var newatri =  ilmfinderimage.replace("[", "").replace("" +
          "]", "")
    Log.d("ffffffffff", newatri)





    Picasso.get()
        .load(newatri)
        .error(R.drawable.qiblacompass)
        .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
        .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
        .into(holder.eventPhoto)




    holder.list_card.setOnClickListener 

        countryList[CategoryID].ilmFinders[position].eventName
        countryList[CategoryID].ilmFinders[position].eventLink
        newatri

        //context.startActivity(Intent(context, LlmNoteDetailsActivity::class.java))

        var intent = Intent(context, LlmNoteDetailsActivity::class.java)
        intent.putExtra("EventName",countryList[CategoryID].ilmFinders[position].eventName)
        intent.putExtra("EventLink",countryList[CategoryID].ilmFinders[position].eventLink)
        intent.putExtra("isFavourite",countryList[CategoryID].ilmFinders[position].isFavourite)
        intent.putExtra("eventId",countryList[CategoryID].ilmFinders[position].eventId)
        intent.putExtra("eventDate",countryList[CategoryID].ilmFinders[position].eventDate)
        intent.putExtra("eventDescription",countryList[CategoryID].ilmFinders[position].eventDescription)
        intent.putExtra("eventLocation",countryList[CategoryID].ilmFinders[position].eventLocation)
        intent.putExtra("eventLink",countryList[CategoryID].ilmFinders[position].eventLink)
        intent.putExtra("EventImage",newatri)
        context.startActivity(intent)

    



class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
    val eventName: TextView = itemView.findViewById(R.id.title_tv2)
    val eventLink: TextView = itemView.findViewById(R.id.tv_url2)
    val eventPhoto: ImageView = itemView.findViewById(R.id.thumbnail_tv2)
    val list_card: ConstraintLayout = itemView.findViewById(R.id.list_constraint)



这是它的布局(list_item2):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/frame_layout"
android:layout_
android:layout_>

<com.bigman.wmzx.customcardview.library.CardView
android:id="@+id/list_card"
android:layout_
android:layout_
app:cardCornerRadius="4dp"
app:contentPadding="8dp">

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/list_constraint"
    android:layout_
    android:layout_>

    <ImageView
        android:id="@+id/thumbnail_tv2"
        android:layout_
        android:layout_
        android:src="@drawable/insta"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="MissingConstraints"
        />

    <TextView
        android:id="@+id/title_tv2"
        android:layout_
        android:textColor="#4B4B4B"
        android:fontFamily="@font/poppins"
        android:textStyle="bold"
        android:textSize="12dp"
        android:maxLength="20"
        android:layout_
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/thumbnail_tv2" />

    <TextView
        android:id="@+id/tv_url2"
        android:maxLength="20"
        android:layout_
        android:layout_
        android:drawablePadding="10dp"
        android:drawableLeft="@drawable/linkiimfinder"
        android:layout_marginTop="8dp"
        android:fontFamily="@font/poppins"
        android:text="TextView"
        android:textSize="12sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title_tv2"
         />




</androidx.constraintlayout.widget.ConstraintLayout>
</com.bigman.wmzx.customcardview.library.CardView>
</FrameLayout>

所以在 (fragment_ilm_note_detail) 布局中有一个 ImageView (id:ImageViewTop) 如果用户点击它,我会尝试全屏显示此图像

我尝试创建新的活动和布局以仅显示图像,如果用户单击图像,我添加了 setOnClickListener 但我遇到了一些错误

实现这一目标的最简单方法是什么?

“请耐心等待,因为我是 Kotlin 的新手”

我已经在网上搜索了将近 3 天来解决这个问题,但我找不到适合我的情况的解决方案,这就是我在这里问的原因,如果您有解决方案,请联系我的代码

【问题讨论】:

【参考方案1】:

您不会在 holder.list_card.setOnClickListener 中创建新活动。相反,创建一个新的片段,它有自己的 xml 布局和 fullScreen imageView。比如fragment的kotlin代码:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.Fragment

class FullScreenImageFragment: Fragment() 

    companion object 
        val TAG: String =  "FullScreenImageFragment"
        val INPUT_IMAGE: String = "INPUT_IMAGE"

        fun getInstance(inputImageUrl: String): FullScreenImageFragment 
            val fullScreenImageFragment = FullScreenImageFragment()
            val args = Bundle()
            args.putString(INPUT_IMAGE, inputImageUrl)
            fullScreenImageFragment.arguments = args
            return fullScreenImageFragment
        
    

    private var inputImageUrl: String = ""
    private lateinit var fragmentRootView: View

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View 
        // return super.onCreateView(inflater, container, savedInstanceState)
        this.fragmentRootView = inflater.inflate(R.layout.full_screen_image, container, false)
        this.fragmentRootView.setOnClickListener  /* empty listener to prevent click propagation */ 
        return fragmentRootView
    

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        initArgument()

        val imagePreview: ImageView = fragmentRootView.findViewById(R.id.imagePreview)
        Picasso.get()
            .load(inputImageUrl)
            .error(R.drawable.qiblacompass)
            .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
            .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
            .into(imagePreview)
    

    private fun initArgument() 
        if(arguments!=null) 
            this.inputImageUrl = requireArguments().getString(INPUT_IMAGE, "")
        
    

xml 布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

    <ImageView
        android:id="@+id/imagePreview"
        android:layout_
        android:layout_/>

</androidx.constraintlayout.widget.ConstraintLayout>

最后,在您的适配器内部:

holder.list_card.setOnClickListener
  val activity: Activity = holder.context as Activity
activity.supportFragmentManager.beginTransaction()
                .replace(android.R.id.content, FullScreenImageFragment.getInstance(newatri))  // "www.some_image_url.com"
                .commit()

这应该可以完成工作。考虑对 Fragments 进行更多研究以进一步修改代码。

【讨论】:

我现在了解布局和片段,但是我需要在适配器中添加的内容我没有得到它并且不起作用,我应该将“holder.context as Activity”替换为“ eventPhoto" 用于上下文?或不?对于“supportFragmentManager”,它的“未解决的参考:supportFragmentManager”以及“.replace(android.R.id.content”,我应该调用什么ID? 尝试``` val activity: AppCompatActivity = itemView.context as AppCompatActivity; activity.supportFragmentManager ```这应该可以解决冲突 它确实解决了问题,现在在“val 活动:AppCompatActivity = itemView.context as AppCompatActivity”中留下了“itemView”,我试图用“eventPhoto”替换它,但它没有用跨度> 以及“.replace(android.R.id.content”,我应该包括什么id?图像id? 试试val activity: AppCompatActivity = holder.itemView.context as AppCompatActivityval activity: AppCompatActivity = context as AppCompatActivity,android.R.id.content是挂载片段的内置布局id。通常我们使用一个frameLayout,这里使用frameLayout的id。由于您没有 frameLayout,而且我不想使事情复杂化,因此我使用了应该可以工作的 android.R.layout.content。【参考方案2】:

解决方案:

所以我在这里做了什么:

我用它的布局创建了新的 Activity:

活动:

    val detailback_btn: ImageButton = findViewById(R.id.detailback_btn2)
    val EventImage = intent.getStringExtra("EventImage")
    val thumbnail_tv22: ImageView = findViewById(R.id.thumbnail_tv22)

    Picasso.get()
        .load(EventImage)
        .error(R.drawable.qiblacompass)
        .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
        .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
        .into(thumbnail_tv22)

    detailback_btn.setOnClickListener 

        onBackPressed()
    
   

我通过图像“val EventImage = intent.getStringExtra("EventImage")”

并从“LlmNoteDetailsActivity”中添加了 setOnClickListener 以打开新的 Activity 并传递图像:

LlmNoteDetailsActivity:

   ImageViewTop.setOnClickListener 
        val intent = Intent(this, LoginActivityV2::class.java)
        intent.putExtra("EventImage",EventImage)
        startActivity(intent)
     

【讨论】:

以上是关于如何在 Kotlin 中显示来自 RecyclerView 的全屏图像?的主要内容,如果未能解决你的问题,请参考以下文章

kotlin Recycler查看分页

如何在 Kotlin 中显示来自 RecyclerView 的全屏图像?

我似乎无法将我的Kotlin Recycler多视图代码整理出来

Recycler View 不显示数据

如何在 JSON 的 Recycler 视图中显示特定类别

如何使用 kotlin 实现分页