Как остановить просмотр в RecyclerView его значения, когда он имеет фокус? - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть RecyclerView с набором CardView, который содержит EditText в каждой карте. Адаптер RecyclerView получает список чисел каждую секунду и связывает данные с EditText каждого CardView.

Однако, когда пользователь нажимает на одну из EditView, я хочу, чтобы EditView переставал меняться каждую секунду, пока EditView имеет фокус, поэтому пользователь может вводить свои собственные данные.

Я действительно не знаю, что делать if (editView.hasFocus)


Адаптер

class ConverterRecyclerViewAdapter(val ratesList: ArrayList<Currency>,
                                   val context: Context?,
                                   val onRateListener: OnRateListener)
    : RecyclerView.Adapter<ConverterRecyclerViewAdapter.ViewHolder>() {

    class ViewHolder(itemView: View, val onRateListener: OnRateListener) : RecyclerView.ViewHolder(itemView), View.OnClickListener{

        var editText: EditText
        init{
            itemView.setOnClickListener(this)
            editText = itemView.findViewById(R.id.value_conv_cv)
        }

        fun bindItem(currency : Currency){
            itemView.currency_name_conv_cv.text = currency.currencyName
            itemView.country_currency_name_conv_cv.text = currency.countryCurrencyName
            itemView.value_conv_cv.text = SpannableStringBuilder(currency.value.toString())
            itemView.flag_iv_conv_cv.setImageResource(currency.flag)
            itemView.tag = currency.currencyName
        }

        override fun onClick(v: View?) {
            onRateListener.onRateClick(adapterPosition, itemView.currency_name_conv_cv.text.toString())
        }
    }

    interface OnRateListener {
        fun onRateClick(position : Int, currency : String)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.converter_card_layout, parent, false)

        return ViewHolder(view, onRateListener)
    }

    override fun getItemCount(): Int {
        return ratesList.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bindItem(ratesList[position])
    }
}

CardView. xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardElevation="0dp"
    app:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">
        <ImageView
            android:id="@+id/flag_iv_conv_cv"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/ic_launcher_round"/>

        <TextView
            android:id="@+id/currency_name_conv_cv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CURRENCY"
            android:textStyle="bold"
            android:textSize="16sp"
            android:paddingTop="@dimen/list_item_tv_padding"
            android:paddingStart="@dimen/list_item_tv_padding"
            android:layout_toRightOf="@id/flag_iv_conv_cv"
            android:layout_toEndOf="@+id/flag_iv_conv_cv"
            android:textColor="@android:color/black"/>

        <TextView
            android:id="@+id/country_currency_name_conv_cv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/flag_iv_conv_cv"
            android:layout_toEndOf="@+id/flag_iv_conv_cv"
            android:layout_below="@+id/currency_name_conv_cv"
            android:paddingStart="@dimen/list_item_tv_padding"
            android:text="Country Currency Name"
            android:textSize="12sp"
            android:textColor="@android:color/darker_gray"/>

        <EditText
            android:id="@+id/value_conv_cv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignEnd="@id/country_currency_name_conv_cv"
            android:gravity="right"
            android:text="100"
            android:textSize="24sp" />
    </RelativeLayout>
</androidx.cardview.widget.CardView>

Фрагмент

override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(ConverterViewModel::class.java)

        viewModel.initialisePositions()
        viewModel.setupTimer(viewModel.ratesPositions[0])

        val ratesLiveData = viewModel.rates
        ratesLiveData.observe(viewLifecycleOwner, Observer { data ->
            refreshData(data.rates)
            viewModel.sortListByPositionsArray(ratesArray)

            val firstElementInRecyclerView = viewModel.ratesPositions[0]
            val view = recyclerView.findViewWithTag<View>(firstElementInRecyclerView)
            lateinit var editText : EditText

            if (converterAdapter == null) setUpRecyclerView()
            else {
                converterAdapter!!.notifyDataSetChanged()
            }
        })
    }

Ответы [ 3 ]

1 голос
/ 26 апреля 2020

Ваш EditText нуждается в специальной привязке, поэтому удалите эту строку из забавного bindItem ():

itemView.value_conv_cv.text = SpannableStringBuilder(currency.value.toString())

А в onBindViewHolder связывайте это представление только тогда, когда оно не сфокусировано, что требует прослушивания. Попробуйте это:

 override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val current = ratesList[position]
    holder.bindItem(current)
    holder.value_conv_cv.setOnFocusChangeListener { view, hasFocus ->
        if (hasFocus) {
            // do nothing
        } else {
            holder.value_conv_cv.text = SpannableStringBuilder(current.value.toString())

        }
    }
}
1 голос
/ 26 апреля 2020

Прежде всего, вы хотите обновить свой предмет, когда у вас нет на нем фокус, поэтому вам действительно нужно использовать if (!editView.hasFocus()) {}

Тогда, если вам нужно проверить, если ваш список ratesArray держит те же предметы или нет, потому что если вы в какой-то момент делаете ratesArray.clear(), вы очищаете объекты, тогда RecyclerView создаст новый ViewHolder для вашего элемента.

Если вы Вы постоянно очищаете и создаете новые объекты, вам необходимо «соединить» ваш адаптер с элементами.

Например, если вы всегда очищаете элементы и создаете их заново, соблюдая положение, добавьте этот метод в свой адаптер:

override fun getItemId(position: Int): Long {
    return position.toLong()
}

Вы можете связать «скорость» любым другим способом (например, String внутри объекта). Если вы делаете это с position, вы соединяете каждый элемент с их порядком.

Теперь, чтобы завершить sh «соблюдение этого порядка», вы должны сообщить адаптеру, что он имеет стабильные идентификаторы , Это сделано с Adapter.setHasStableIds(true)

1 голос
/ 26 апреля 2020

Может быть так:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    if(!holder.editText.hasFocus()){
    holder.bindItem(ratesList[position])
    }

}

ОБНОВЛЕНИЕ

удалить атрибут focusable для текста редактирования и добавить его в xml

 android:focusableInTouchMode="false"

в адаптере:

 //decalare clicked item as member of the class and set it to -1

 var clickedItem = -1;

override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    if(clickedItem != position){
    holder.bindItem(ratesList[position])

     }

    //on click
     holder.editText.setOnClickListener {

       clickedItem = position;
       notifyDataSetChanged();
     }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...