如何在 Binding Adapter 中将此 java 代码写入 kotlin

Posted

技术标签:

【中文标题】如何在 Binding Adapter 中将此 java 代码写入 kotlin【英文标题】:How to write this java code to kotlin in Binding Adapter 【发布时间】:2021-04-28 11:39:10 【问题描述】:

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

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

    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_
    android:layout_
    android:orientation="horizontal"
    android:paddingStart="16dp"
    android:paddingLeft="16dp"
    android:paddingEnd="16dp"
    android:paddingRight="16dp">
    
    <TextView
        android:id="@+id/magnitude"
        android:layout_
        android:layout_
        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_
        android:layout_
        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_
            android:layout_
            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_
            android:layout_
            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_
        android:layout_
        android:layout_gravity="center_vertical"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/date"
            android:layout_
            android:layout_
            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_
            android:layout_
            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 编程的新手。

【问题讨论】:

【参考方案1】:

基本上规则是反转语法。如果你在 kotlin 中有 String originalLocation = properties.getPlace();,那就是 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。

【讨论】:

是的,我知道除了这里之外,我没有在onBindViewHolder 方法中使用findviewbyId,如果是这样的话,我会这样做..我正在尝试使用从我的RecyclerviewAdapter.kt 代码中可以看到数据绑定。我不知道如何实现@BindingAdapter("place") 中的代码,这就是问题所在,@Piotr

以上是关于如何在 Binding Adapter 中将此 java 代码写入 kotlin的主要内容,如果未能解决你的问题,请参考以下文章

如何在 wamp 服务器的 phpmyadmin 中将此数据数组插入 mysql

SwiftUI 中的 @Binding 和 ForEach

android data binding jetpack V

如何在 JavaFX 中将 CheckBox 添加到 TableView

记一次 Data Binding 在 library module 中遇到的大坑

如何在 Spring Security 中将令牌转换为身份验证?