Как изменить текст textview внутри основного действия из класса адаптера recyclerview

#android #kotlin #android-recyclerview #textview

#Android #kotlin #android-recyclerview #textview

Вопрос:

Я использую представление recycler во фрагменте, который загружается в основное действие.При нажатии на мой элемент просмотра recycler я хочу установить текст в textview, который находится внутри основного действия. Я пытался сделать это:

 displayText(MainActivity(),R.id.name,"Text you want to display");
            MainActivity().textView!!.setText(name)

 fun displayText(activity: Activity, id:Int, text:String) {
        val tv = activity.findViewById(id) as TextView
        tv.setText(text)
    }
  

Но это не работает, мое приложение вылетает
Пожалуйста, помогите мне отладить это, поскольку я все еще новичок, любая помощь будет оценена.

Это мой основной класс activity:

     class MainActivity : AppCompatActivity() {
        private var adapter: Tabadapter? = null
        private var tabLayout: TabLayout? = null
        private var viewPager: ViewPager? = null
        var PlayPauseView : PlayPauseView? = null
        var textView : TextView?=null
         var context : Context?=null
        var slidingUpPanelLayout : SlidingUpPanelLayout?=null
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            Dexter.withActivity(this)
                    .withPermissions(
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE
                    ).withListener(object : MultiplePermissionsListener {
                        override fun onPermissionsChecked(report: MultiplePermissionsReport) {/* ... */
                        }

                        override fun onPermissionRationaleShouldBeShown(permissions: List<PermissionRequest>, token: PermissionToken) {/* ... */
                        }
                    }).check()
            viewPager = findViewById<View>(R.id.viewPager) as ViewPager
            tabLayout = findViewById<View>(R.id.tabLayout) as TabLayout
            adapter = Tabadapter(supportFragmentManager)
            adapter!!.addFragment(Songs(), "Songs")
            adapter!!.addFragment(Playlist(), "Playlist")
            adapter!!.addFragment(Folders(), "Folders")
            adapter!!.addFragment(Albums(), "Albums")
            adapter!!.addFragment(Artists(), "Artists")
            adapter!!.addFragment(Genres(), "Genres")
            viewPager!!.adapter = adapter
            tabLayout!!.setupWithViewPager(viewPager)
            slidingUpPanelLayout = findViewById(R.id.sliding_layout)
            PlayPauseView=findViewById(R.id.play_pause_view)
            PlayPauseView!!.setOnClickListener{v->
                PlayPauseView!!.toggle()
            }
            textView = findViewById(R.id.name)
            textView!!.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate) as Animation)
            slidingUpPanelLayout!!.addPanelSlideListener(object : SlidingUpPanelLayout.PanelSlideListener {
                override fun onPanelSlide(panel: View, slideOffset: Float) {

                }

                override fun onPanelStateChanged(panel: View, previousState: PanelState, newState: PanelState) {
                    Log.i("State", "onPanelStateChanged $newState")
                }
            })


        }
        fun update_counter(value:String) {
            try
            {
                runOnUiThread() {
                    textView = findViewById(R.id.name)
                    textView !!.setText(value)
                }
               // val mHandler = Handler()

                //textView!!.text=value
            }
            catch (ex:Exception) {
                Log.d("Exception", "Exception of type"   ex.message)
            }
        }
    }
  

Это мой класс адаптера:

 class Songsadapter(private val sname: List<String>, private val sartist: List<String>, private val surl : List<String>, internal var mContext: Context) : RecyclerView.Adapter<Songsadapter.ProjectViewHolder>() {

    var mPlayer : MediaPlayer?=null
     var ps : Int?=null
    override fun onCreateViewHolder(parent: ViewGroup, i: Int): ProjectViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val view = layoutInflater.inflate(R.layout.custom_songs, parent, false)
        return ProjectViewHolder(view)
    }

    override fun onBindViewHolder(holder: ProjectViewHolder, position: Int) {
        val pos = holder.adapterPosition
        var name = sname.get(pos)
        var artist = sartist.get(pos)
        var songurl = surl.get(pos)
        try {
            var metaRetriver: MediaMetadataRetriever
            metaRetriver = MediaMetadataRetriever()
            metaRetriver.setDataSource(songurl)
            var art: ByteArray
            art = metaRetriver.embeddedPicture
            var songImage = BitmapFactory.decodeByteArray(art, 0, art.size)
            var ob: BitmapDrawable = BitmapDrawable(mContext.getResources(), songImage)
            holder.covimg!!.setBackgroundDrawable(ob)
        }catch (e: Exception){
            e.printStackTrace()
        }
        holder.tvsname.text = name
        holder.tvsartist.text = artist
        holder.itemView.setOnClickListener(View.OnClickListener {
            MainActivity().update_counter(name)
            stoplaying()
            var i:Int = pos
            mPlayer = MediaPlayer()
            mPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
            mPlayer!!.setDataSource(mContext.getApplicationContext(), Uri.parse(songurl))
            mPlayer!!.prepare()
            mPlayer!!.start()
            mPlayer!!.setOnCompletionListener {
                i = i 1
                mPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mPlayer!!.setDataSource(mContext.getApplicationContext(), Uri.parse(surl.get(i)))
                mPlayer!!.prepare()
                mPlayer!!.start()
            }
        })

    }

    override fun getItemCount(): Int {

        return sname.size

    }

    inner class ProjectViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        var tvsname: TextView
        var tvsartist: TextView
        var covimg: ImageView


        init {
            tvsname = itemView.findViewById(R.id.sname)
            tvsartist = itemView.findViewById(R.id.sartist)
            covimg = itemView.findViewById(R.id.imgscov)
        }
    }
fun stoplaying(){
    if (mPlayer != null) {
        mPlayer!!.stop()
        mPlayer!!.release()
        mPlayer = null
    }
}
}
  

Ответ №1:

Используйте интерфейс, чтобы получить обратный вызов элемента RecylcerView внутри класса activity. Если вам неудобно использовать интерфейс, найдите в Google информацию об интерфейсе или попросите меня привести пример кода.

1. Интерфейс:

 interface OnAdapterItemClickListener {
    fun onItemClicked(id: Int, text: String)
}
  

2. Ваш класс адаптера

 class Songsadapter(private val clickListener: OnAdapterItemClickListener, private val sname: List<String>, private val sartist: List<String>, private val surl : List<String>, internal var mContext: Context) : RecyclerView.Adapter<Songsadapter.ProjectViewHolder>() {
//adapter code
}
  

3. Внедрите интерфейс в свой фрагмент

     class SearchFragment : Fragment(), OnAdapterItemClickListener{

    private var mListener: OnAdapterItemClickListener? = null

    fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnAdapterItemClickListener) {
            mListener = context as OnAdapterItemClickListener
        } else {
            throw RuntimeException("$context must implement OnFragmentInteractionListener")
        }
    }

        fun onViewCreated(@NonNull view: View, @Nullable savedInstanceState: Bundle) {
            super.onViewCreated(view, savedInstanceState)

           //add fist parameter as 'this'
           Songsadapter mAdapter = Songsadapter(this, others.....,  )

    }   
        fun onItemClicked(id: Int, text: String) {
        //You're getting click callback here in fragment
         mListener.onItemClicked(id, text)
                }
    }
  

4. Внедрите интерфейс и в свое действие

 class MainActivity : AppCompatActivity(), OnAdapterItemClickListener {

override fun onItemClicked(id: Int, text: String) {
        //here you go
        Log.i("clicked: ", text)
        val tv = findViewById(id) as TextView
        tv.setText(text)
    }

}
  

Комментарии:

1. Да, пожалуйста, поместите код, в котором я не разбираюсь в интерфейсе в kotlin, который будет очень полезен

2. Эй, пожалуйста, разместите свои сегменты кода (конструктор адаптера и его использование), чтобы я мог использовать это для вашего лучшего понимания.

3. Вы наверняка использовали адаптер в классе fragment, верно??

4. Да, класс адаптера инициализирован в классе fragment

5. Я действительно застрял, пожалуйста, помогите мне исправить это