首页 > 解决方案 > 如何在 Binding Adapter 中将此 java 代码写入 kotlin

问题描述

我在 lang (java) 中用 onBindViewHolder 编写了几行代码。我正在尝试在 Binding Adapter 的 kotlin 中编写确切的代码,但我无法编写

EarthQuakeAdapter( JAVA) .. 我试过了,但我无法编写相同的代码来从 onBindViewHolder(JAVA lang) 方法中获取 MagarCircle 、 PrimaryLocation 和 LocationOffSet 到 kotlin 中的绑定适配器,我在下面发布了

    public class EarthquakeAdapter extends RecyclerView.Adapter<EarthquakeAdapter.MyViewHolder> {


    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int i) {

        Properties properties = this.mData.get(i).getProperties();
        double earthquakeMagnitude = properties.getMag();
        DecimalFormat decimalFormat = new DecimalFormat("0.0");
        String formattedMagnitude = decimalFormat.format(earthquakeMagnitude);
        holder.tvMagnitude.setText(formattedMagnitude);
                    
        // Set the proper background color on the magnitude circle.
        // Fetch the background from the TextView, which is a GradientDrawable.
        holder.magnitudeCircle = (GradientDrawable) holder.tvMagnitude.getBackground();

        //Get the appropriate background color based on the current earthquake magnitude
        int magnitudecolor = getMagnitudeColor(properties.getMag());
                
        //Set the color on the magnitude circle
        holder.magnitudeCircle.setColor(magnitudecolor);

         //Get the original location string from the earthquake object ,
        // which can be in the format of "5km N of Cairo, Egypt" or "Pacific-Antartic Ridge' .        
        //If the original location String (i.e, 5km of Cairo , Egypt ) contains
        //a primary location (Cario, Egypt) and a location offset (5km of that city )
        //then store the primary location separately from the location offset in 2 strings,
        //so they can be displayed in two TextViews.

         String originalLocation = properties.getPlace();


        //Check whether the originalLocation string contain the "of" text
        if (originalLocation.contains("of")) {
            //Split the string into different parts (as an array of strings)
            //based on the "of" text. We expect an array of two strings, where
            // the first string will , be " 5km N" and the second string will be 'Cairo Egypt"

            String[] parts = originalLocation.split("of");
            //location offset should be "5km N" +  " of " ---> "5km N of'
            //Primary location should be "Cairo Egypt"

            holder.tvLocationOffSet.setText(parts[0] + "of");
            holder.tvPrimaryLocation.setText(parts[1]);

        } else {
            //otherwise , there is no " of " text in the originalLocation string .
            //Hence, the default location offset to say " Near the"
            holder.tvLocationOffSet.setText("Near The");
            holder.tvPrimaryLocation.setText(originalLocation);
        }
    }


    public static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvMagnitude, tvLocationOffSet, tvPrimaryLocation, 
        GradientDrawable magnitudeCircle;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvMagnitude = itemView.findViewById(R.id.magnitude);
            tvLocationOffSet = itemView.findViewById(R.id.location_offset);
            tvPrimaryLocation = itemView.findViewById(R.id.primary_location);            
        }
    }
   
    private int getMagnitudeColor(double magnitude) {
        int magnitudeColorResourceId;
        int magnitudeFloor = (int) Math.floor(magnitude);
        switch (magnitudeFloor) {
            case 0:
            case 1:
                magnitudeColorResourceId = R.color.magnitude1;
                break;
            case 2:
                magnitudeColorResourceId = R.color.magnitude2;
                break;
            case 3:
                magnitudeColorResourceId = R.color.magnitude3;
                break;
            default:
                magnitudeColorResourceId = R.color.magnitude10plus;
                break;
        }

        return ContextCompat.getColor(mContext, magnitudeColorResourceId);
    }

}

BindingAdapter.kt(KOTLIN)

 @BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: EarthquakeResponse?) {
    val adapter = recyclerView.adapter as RecyclerviewAdapter
    if (data != null) {
        adapter.submitList(data.features?.toList())
    }
}

@BindingAdapter("magnitude")
fun bindAuthor(textView: TextView, magName : Double) {
   val decimalFormat = DecimalFormat("0.0")
    val formattedMagnitude = decimalFormat.format(magName)
    textView.setText(formattedMagnitude.toString())
}

@BindingAdapter("place")
fun bindTitle(textView: TextView, titlePlace : String) {
    textView.setText(titlePlace)
//    if (titlePlace.contains("of")) {
//        @BindingAdapter("placeone")
//        fun bindPlaceOne(textView: TextView, titlePlace: String) {
//            var parts = titlePlace.split("of").toString()
//            textView.setText(parts[0] + "of")
//
//    @BindingAdapter("placetwo")
//    fun bindPlaceTwo(textView: TextView, titlePlace: String) {
//        textView.setText(parts[1].toString())
//    }
//        }
//
//    } else {
//        @BindingAdapter("placeone")
//        fun bindPlaceOne(textView: TextView, titlePlace: String) {
//
//            textView.setText( "NEAR THE") }
//
//        @BindingAdapter("placetwo")
//        fun bindPlaceTwo(textView: TextView, titlePlace: String) {
//            textView.setText(titlePlace)
//        }
//    }
}

@BindingAdapter("time")
fun bindTime(textView: TextView, titleTime :Long) {
    // SimpleDateFormat timeFormat = new SimpleDateFormat("h:mm a");
    val timeFormat = SimpleDateFormat("h:mm a")
    val formattedTime = timeFormat.format(titleTime)
    textView.setText(formattedTime.toString())

}


@BindingAdapter("date")
fun bindDate(textView: TextView, titleTime :Long) {
    val timeFormat = SimpleDateFormat("LLL dd, yyyy")
    val formattedDate = timeFormat.format(titleTime)
    textView.setText(formattedDate.toString())

}

RecyclerviewAdapter.kt

 class RecyclerviewAdapter() : ListAdapter<Feature, RecyclerviewAdapter.EarthquakePropertyViewHolder>(DiffCallback()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EarthquakePropertyViewHolder {
        return EarthquakePropertyViewHolder.from(parent)
    }

    override fun onBindViewHolder(holder: EarthquakePropertyViewHolder, position: Int) {
        val item = getItem(position)
        holder.bind(item)
    }
    class EarthquakePropertyViewHolder private constructor(val binding: EarthquakeRawBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(books: Feature) {
            binding.property = books
            binding.executePendingBindings()
        }
        companion object {
            fun from(parent: ViewGroup): EarthquakePropertyViewHolder {
                val layoutInflater = LayoutInflater.from(parent.context)
                val view = EarthquakeRawBinding.inflate(layoutInflater, parent, false)
                return EarthquakePropertyViewHolder(view)
            }
        }
    }
}

class  DiffCallback : DiffUtil.ItemCallback<Feature>() {
    override fun areItemsTheSame(oldItem: Feature, newItem: Feature): Boolean {
        return oldItem === newItem
    }
    override fun areContentsTheSame(oldItem: Feature, newItem: Feature): Boolean {
        return oldItem == newItem

    }
}

Earthquake_raw.xml

 <layout
    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" >

    <data>
        <variable
            name="property"
            type="com.example.kotlinearthquake.network.Feature" />
    </data>

<LinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    android:orientation="horizontal"
    android:paddingStart="16dp"
    android:paddingLeft="16dp"
    android:paddingEnd="16dp"
    android:paddingRight="16dp">
    
    <TextView
        android:id="@+id/magnitude"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_gravity="center_vertical"
        android:background="@drawable/magnitude_circle"
        android:fontFamily="sans-serif-medium"
        android:gravity="center"
        android:textColor="@android:color/black"
        android:textSize="16sp"
        app:magnitude="@{property.properties.mag}"
        tools:text="8.9" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/location_offset"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:fontFamily="sans-serif-medium"
            android:maxLines="1"
            android:textAllCaps="true"
            android:textColor="@android:color/black"
            android:textSize="12sp"
            tools:text="30km S of" />

        <TextView

            android:id="@+id/primary_location"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="2"
            android:textColor="@android:color/black"
            android:textSize="12sp"
            app:place="@{property.properties.place}"
            tools:text="Long placeholder that should wrap to more than 2 line of text" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textColor="@color/textColorEarthquakeDetails"
            android:textSize="12sp"
            app:date="@{property.properties.time}"
            tools:text="Mar 6, 2010" />

        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textColor="@color/textColorEarthquakeDetails"
            android:textSize="12sp"
            app:time="@{property.properties.time}"
            tools:text="3:00 PM" />
    </LinearLayout>
</LinearLayout>
</layout>

请帮助我,我还是 Kotlin 编程的新手。

标签: androidkotlindata-bindingbinding

解决方案


基本上规则是反转语法。如果你有String originalLocation = properties.getPlace();kotlin 那将是var/val originalLocation: String = properties.getPlace(). Var 代表变化的变量,val 代表不变的值。您可以绕过定义对象的类型,因为 kotlin 足够聪明,可以知道不同类型的初始化属性。voidfun并且您不需要指定它是否是公共的,因为它是默认的,除非您另有说明。class两者都是相同的,并且函数中的变量是反向声明的, (@NonNull MyViewHolder holder, int i)所以(holder: MyViewHolder, i: Int).

当然,Android Studio 有这个很棒的选项,当你将 java 代码复制到 kotlin 文件时,它会询问你是否要将其更改为 kotlin。


推荐阅读