Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
88 views
in Technique[技术] by (71.8m points)

android - How to write this java code to kotlin in Binding Adapter

I have some lines of code written in onBindViewHolder in lang (java) .. I'm trying to write the exact code in kotlin in Binding Adapter , but i'm not able to write that

EarthQuakeAdapter( JAVA) .. I tried but i was not able to write the same code to get magnitudeCircle , PrimaryLocation and LocationOffSet from onBindViewHolder(JAVA lang) method to Binding Adapter in kotlin which i posted below

    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:dat

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Basically the rule is to reverse syntax. If you have String originalLocation = properties.getPlace(); in kotlin that would be var/val originalLocation: String = properties.getPlace(). Var stands for variable that changes and val is for unchangeable values. You can bypass defining object's type because kotlin is smart enough to know the different types of initialized properties. void is fun and you don't need to specify if it's public because it is by default unless you say otherwise. class is the same in both and variables in functions are declared in reverse so (@NonNull MyViewHolder holder, int i) would be (holder: MyViewHolder, i: Int).

Of course Android Studio has this magnificent option that, when you copy java code into kotlin file, it will ask you if you want it changed to kotlin.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...