javaandroidandroid-studiokotlincode-conversion

Isuues after converting project from java to kotlin


Hello there after a long time thinking about converting my project from java to kotlin , today I shift from java to kotlin , and as expected and warned by the community that the project will not magically just transfer everything easily to kotlin, there are errors now

ok I just make it clear I'm a very beginner in kotlin but I was somewhat familiar with java

there are as I noticed 1 main error with almost all the converted java to kotlin files

Smart cast to 'RecyclerView!' is impossible, because 'postRecyclerView' is a mutable property that could have been changed by this time

in java, for eg if I have to add a scroll listener I just do this

recyclerview.addOnScrollListner 

but getting error in kotlin // below is lines are kotlin

postRecyclerView.setLayoutManager(
            staggeredGridLayoutManager
        )

or

 postRecyclerView.addOnScrollListener 

or

shimmerFrameLayout.startShimmer()

as I don't know much about kotlin I don't know what it is

and secondly, in my old java adapter class, I have

public static List<Upload> mUploads;

but now as converted in kotlin I'm facing an issue with mUploads for eg on this line

val uploadCurrent: Upload = Companion.mUploads.get(position)

getting error on mUploads it is showing Unresolved reference: mUploads

Old java adapter class code

PostAdapter_Home.java

public class PostAdapter_Home extends RecyclerView.Adapter<PostAdapter_Home.PostViewHolder> {
    public static List<Upload> mUploads;
    public Context mcontext;

    public PostAdapter_Home(Context context, List<Upload> uploads) {
        mUploads = uploads;
        mcontext = context;
    }


    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(mcontext).inflate(R.layout.ex_home, parent, false);
        return new PostViewHolder(view);

    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
        Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
                .setBaseColor(Color.parseColor("#F3F3F3"))
                .setBaseAlpha(1)
                .setHighlightColor(Color.parseColor("#E7E7E7"))
                .setHighlightAlpha(1)
                .setDropoff(50)
                .build();
        ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
        shimmerDrawable.setShimmer(shimmer);
        Upload uploadCurrent = mUploads.get(position);
        Glide.with(mcontext)
                .load(uploadCurrent.getmImageUrl())
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .placeholder(shimmerDrawable)
                .centerCrop()
                .fitCenter()
                .into(holder.imageView);

//        holder.imageView.setOnClickListener(view -> changeScaleType(holder, position));

    }


    @Override
    public int getItemCount() {
        return mUploads.size();
    }

    public void setUploads(List<Upload> uploads){
        mUploads=uploads;
    }
    public static class PostViewHolder extends RecyclerView.ViewHolder {

        private final ShapeableImageView imageView;

        public PostViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imagePostHome);

        }


    }
} 

PostAdapter.kt

class PostAdapter     /* ShimmerFrameLayout shimmerFrameLayout; */(
    var mcontext: Context
) : RecyclerView.Adapter<PostAdapter.PostViewHolder>() {
    private var mListener: OnItemClickListener? = null
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
        LayoutInflater.from(mcontext).inflate(R.layout.post_item_container_profile, parent, false)
        val view: View = LayoutInflater.from(parent.context)
            .inflate(R.layout.post_item_container_profile, parent, false)
        return PostViewHolder(view)
    }

    override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
        val uploadCurrent: Upload? = mUploads.get(position)
        val shimmer = ColorHighlightBuilder()
            .setBaseColor(Color.parseColor("#F3F3F3"))
            .setBaseAlpha(1f)
            .setHighlightColor(Color.parseColor("#E7E7E7"))
            .setHighlightAlpha(1f)
            .setDropoff(50f)
            .build()
        val shimmerDrawable = ShimmerDrawable()
        shimmerDrawable.setShimmer(shimmer)
        Glide.with(mcontext)
            .load(uploadCurrent.getmImageUrl())
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .placeholder(shimmerDrawable)
            .centerCrop()
            .fitCenter()
            .into(holder.imageView)
    }

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

    fun setOnItemClickListener(listener: OnItemClickListener?) {
        mListener = listener
    }

    fun setUploads(uploads: List<Upload>) {
        Companion.mUploads = uploads
    }

    interface OnItemClickListener {
        fun onClick(view: View?)
        fun onItemClick(position: Int)
        fun onDeleteClick(position: Int)
    }

    inner class PostViewHolder internal constructor(itemView: View) :
        RecyclerView.ViewHolder(itemView), View.OnClickListener, OnCreateContextMenuListener,
        MenuItem.OnMenuItemClickListener {
        var imageView: ShapeableImageView
        override fun onClick(v: View) {
            if (mListener != null) {
                val position = adapterPosition
                if (position != RecyclerView.NO_POSITION) {
                    mListener!!.onItemClick(position)
                }
            }
        }

        override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo) {
            val delete = menu.add(Menu.NONE, 2, 2, "Delete")
            delete.setOnMenuItemClickListener(this)
        }

        override fun onMenuItemClick(item: MenuItem): Boolean {
            if (mListener != null) {
                val position = adapterPosition
                if (position != RecyclerView.NO_POSITION) {
                    if (item.itemId == 2) {
                        mListener!!.onDeleteClick(position)
                        return true
                    }
                }
            }
            return false
        }

        init {
            imageView = itemView.findViewById(R.id.imagePost)
            itemView.setOnClickListener(this)
            itemView.setOnCreateContextMenuListener(this)
        }
    }

    companion object
}

Solution

  • It happens because in kotlin, There're **two ways to declare variables.

    Using lateinit keyword : no need to initialize while declaration.

    Using null as initial value for variable.

    So when you converted java files to kotlin it may have initialized your values with null So you can add !! or ? operator at end of variable for null safety which is initialized as null.

    example.

    postRecyclerView!!.setLayoutManager(
                staggeredGridLayoutManager
            )
     postRecyclerView!!.addOnScrollListener
    

    for more you can check this link Null Safety Kotlin

    In kotlin, static variables (Which can be accessed only with class name) are under companion object blocks

       companion object{
        //your variables here
        }
    

    As you're using mUploads inside same class, You don't need to access it with class name. Use

    mUploads.get(position)
    

    instead of

    Companion.mUploads.get(position)