Я хочу получить класс, производный от класса LinearSmoothScroller, в котором я мог бы передать свойство скорости прокрутки конструктором класса.Ниже приведен код, который работает и добавил несколько println()
для тестов.
Класс ScrollerManager:
class ScrollerManager(
val context: Context,
private var millisecondsPerInch: Float
) : LinearSmoothScroller(context) {
init {
println("init millisecsPerInch: $millisecondsPerInch, instance: $this")
}
fun printSpeed() {
println("printSpeed(): $millisecondsPerInch, instance: $this")
}
override fun getHorizontalSnapPreference(): Int {
return LinearSmoothScroller.SNAP_TO_START
}
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
println("calcSpeedPerPixel(..) millisecsPerInch: ${this.millisecondsPerInch}, instance: $this")
// Here I want to use millisecondsPerInch field value, instead of written value 30f:
return 30f / displayMetrics?.densityDpi!!
}
}
Интерфейс прослушивателя щелчка элемента:
interface RecItemClickListener {
fun onClick(view: View, position: Int)
}
Адаптер.Context, RecyclerView и itemList передаются из Actvity.При щелчке по элементу recyclerView вызывается метод scrollToPosition, в котором используется мой SmoothScroller.
class AdvancedRecViewHoriAdapter(
val context: Context,
val recyclerView: RecyclerView,
val itemsList: List<String>
) : RecyclerView.Adapter<AdvancedRecViewHoriCustomViewHolder>() {
companion object {
var selectedPosition = RecyclerView.NO_POSITION
}
override fun getItemCount(): Int {
return itemsList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
: AdvancedRecViewHoriCustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
// inflate layout from xml
val cellForRow = layoutInflater.inflate(
R.layout.rec_view_advanced_hori_row, parent, false)
return AdvancedRecViewHoriCustomViewHolder(cellForRow)
}
private fun scrollToPosition(position: Int) {
val smoothScroller = ScrollerManager(context, 30f)
smoothScroller.printSpeed()
smoothScroller.targetPosition = position
recyclerView.layoutManager.startSmoothScroll(smoothScroller)
}
override fun onBindViewHolder(holder: AdvancedRecViewHoriCustomViewHolder, position: Int) {
val itemName = itemsList[position]
itemView.rec_view_adv_hori_row_text_view_id.text = itemName
holder.itemClickListener = object : RecItemClickListener {
override fun onClick(view: View, position: Int) {
selectedPosition = position // Update layout position of clicked item.
scrollToPosition(position)
}
}
}
}
Пользовательский ViewHolder:
class AdvancedRecViewHoriCustomViewHolder(val view: View) :
RecyclerView.ViewHolder(view), View.OnClickListener {
var itemClickListener: RecItemClickListener? = null
init {
view.setOnClickListener(this@AdvancedRecViewHoriCustomViewHolder)
}
override fun onClick(view: View) {
try {
itemClickListener?.onClick(view, adapterPosition)
} catch (exception: NullPointerException) {
Log.e("NullPointerException", "Item view is null")
}
}
}
Проблема заключается в том, что при щелчке по одному из recyclerViewэлементы, которые я получаю, системные отпечатки, как это.Поскольку Павел дал совет, я проверил и добавляю адреса экземпляров.Но отпечатки поступают из одних и тех же экземпляров, поэтому эта проблема не решается.
I/System.out:
calcSpeedPerPixel(..) inchPerMilisecs: 0.0, instance: com.example.danielg.loginviewexercise.ScrollerManager@1c4f5c5
init inchPerMilisecs: 30.0, instance: com.example.danielg.loginviewexercise.ScrollerManager@1c4f5c5
printSpeed(): 30.0, instance: com.example.danielg.loginviewexercise.ScrollerManager@1c4f5c5
Вопрос в том, почему millisecsPerInch
не имеет значения, переданного в конструкторе класса ScrollerManager, и его значение равно 0.0
?
Я провел некоторое исследование и изучил реализацию класса LinearSmoothScroller.Возможно, проблема в том, что calculateSpeedPerPixel
метод protected
.Я также рассмотрел переопределение значения MILLISECONDS_PER_INCH
свойства, но оно final
.
Список из файла LinearSmoothScroller.java:
private static final float MILLISECONDS_PER_INCH = 25f;
...
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}