Android Studio : Cara agar data tdk double dan state tetap ada

Hai semuanya , mau tanya gimana cara agar data tdk double saat diinput ke favorit sama statenya masih ada.

Berikut codenya

Detailuser

package com.wibu.picodiploma.submissionakhir.Detail

import android.content.ContentValues
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.PersistableBundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.google.android.material.tabs.TabLayout
import com.loopj.android.http.AsyncHttpClient
import com.loopj.android.http.AsyncHttpResponseHandler
import com.wibu.picodiploma.submissionakhir.Adapter.SectionsPagerAdapter
import com.wibu.picodiploma.submissionakhir.Database.DatabaseContract.FavoritColumns.Companion.CONTENT_URI
import com.wibu.picodiploma.submissionakhir.Database.DatabaseContract.FavoritColumns.Companion.GAMBARPP
import com.wibu.picodiploma.submissionakhir.Database.DatabaseContract.FavoritColumns.Companion.USERNAME
import com.wibu.picodiploma.submissionakhir.Favorit.FavoritAdapter
import com.wibu.picodiploma.submissionakhir.Favorit.FavoritHelper
import com.wibu.picodiploma.submissionakhir.Main.NamaUN
import com.wibu.picodiploma.submissionakhir.MappingHelper
import com.wibu.picodiploma.submissionakhir.R
import com.wibu.picodiploma.submissionakhir.databinding.ActivityDetailuserBinding
import cz.msebera.android.httpclient.Header
import kotlinx.android.synthetic.main.activity_detailuser.*
import org.json.JSONObject

class DetailuserActivity : AppCompatActivity(), View.OnClickListener {

    private lateinit var binding: ActivityDetailuserBinding
    private var FavoritAnda = false
    private lateinit var adapter: FavoritAdapter
    private lateinit var favoritHelper: FavoritHelper
    private var favorit: NamaUN? = null
    private lateinit var gambarpp: String
    private lateinit var uriWithId: Uri
    private lateinit var uriId : Uri
    private var position: Int = 0
    private val FavoritList = "FavoritList"
    private val detailuser = NamaUN()
    private val listfavorit = DetailuserActivity

    companion object {
        const val EXTRA_DETAIL = "extra_detail"
        const val RESULT_ADD = 101
        const val REQUEST_UPDATE = 200
        const val EXTRA_STATE = "EXTRA_STATE"
        const val EXTRA_FAVORIT = "FavoritList"
        const val EXTRA_POSITION = "PositionList"
        const val RESULT_UPDATE = 201
        const val RESULT_DELETE = 301

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDetailuserBinding.inflate(layoutInflater)
        setContentView(binding.root)

        favoritHelper = FavoritHelper.getInstance(applicationContext)
        favoritHelper.open()

        favorit = intent.getParcelableExtra(EXTRA_FAVORIT)
        if (favorit != null) {
            position = intent.getIntExtra(EXTRA_POSITION, 0)
            FavoritAnda = true

        } else {
            favorit = NamaUN()
        }

        val usernameFromMain = intent.getStringExtra(EXTRA_DETAIL)

        //Hanya loading yg muncul
        binding.tvLoading.visibility = View.VISIBLE
        binding.progressSearch.visibility = View.VISIBLE
        binding.textRepost.visibility = View.INVISIBLE
        binding.textFollowers.visibility = View.INVISIBLE
        binding.textFollowing.visibility = View.INVISIBLE
        binding.textinfo.visibility = View.INVISIBLE
        binding.line2.visibility = View.INVISIBLE
        binding.gambarlocation.visibility = View.INVISIBLE
        binding.gambarperusahaan.visibility = View.INVISIBLE
        binding.gambarprofile.visibility = View.INVISIBLE
        binding.tabs.visibility = View.INVISIBLE

        loadDetail(usernameFromMain.toString())

        //Untuk follower dan following
        val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager)
        sectionsPagerAdapter.setUsername(usernameFromMain.toString())
        view_pager.adapter = sectionsPagerAdapter

        val viewPager: ViewPager = findViewById(R.id.view_pager)
        val tabs: TabLayout = findViewById(R.id.tabs)
        tabs.setupWithViewPager(viewPager)
        supportActionBar?.elevation = 0f
        fab_favor.setOnClickListener(this)

    }

    override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
        super.onSaveInstanceState(outState, outPersistentState)
        outState.putParcelableArrayList(EXTRA_STATE, adapter.listFavorit)
    }

    //Mengirimkan data ke detail
    private fun loadDetail(username: String) {
        val client = AsyncHttpClient()
        val url = "https://api.github.com/users/$username"
        client.addHeader("Authorization", "token 56f5906118f42e21825e41107f6e6390fac0f6ac")
        client.addHeader("User-Agent", "request")

        client.get(url, object : AsyncHttpResponseHandler() {
            override fun onSuccess(
                statusCode: Int,
                headers: Array<out Header>?,
                responseBody: ByteArray
            ) {
                binding.tvLoading.visibility = View.INVISIBLE
                binding.progressSearch.visibility = View.INVISIBLE
                binding.textRepost.visibility = View.VISIBLE
                binding.textFollowers.visibility = View.VISIBLE
                binding.textFollowing.visibility = View.VISIBLE
                binding.line2.visibility = View.VISIBLE
                binding.textinfo.visibility = View.VISIBLE
                binding.gambarlocation.visibility = View.VISIBLE
                binding.gambarperusahaan.visibility = View.VISIBLE
                binding.gambarprofile.visibility = View.VISIBLE
                binding.tabs.visibility = View.VISIBLE

                val result = String(responseBody)
                Log.d("Detailuser", result)
                try {
                    val item = JSONObject(result)
                    val username = item.getString("login")
                    val avatar = item.getString("avatar_url")
                    val name = item.getString("name")
                    val company = item.getString("company")
                    val location = item.getString("location")
                    val repos = item.getString("public_repos")
                    val follower = item.getString("followers")
                    val following = item.getString("following")

                    detailuser.username = username
                    detailuser.profile_picture = avatar
                    detailuser.fullname = name
                    detailuser.company = company
                    detailuser.lcoation = location
                    detailuser.repos = repos
                    detailuser.followers = follower
                    detailuser.following = following

                    tv_repost.text = detailuser.repos
                    tv_follow.text = detailuser.followers
                    tv_following.text = detailuser.following

                    tv_une.text = detailuser.username
                    Glide.with(this@DetailuserActivity)
                        .load(detailuser.profile_picture)
                        .apply(RequestOptions().override(90, 90))
                        .into(pp)

                    if (name != "null") {
                        tv_fn.text = detailuser.fullname
                    } else {
                        tv_fn.text = "No data"
                    }

                    if (location != "null") {
                        tv_location.text = detailuser.lcoation
                    } else {
                        tv_location.text = "No data"
                    }

                    if (company != "null") {
                        tv_company.text = detailuser.company
                    } else {
                        tv_company.text = "No data"
                    }

                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }

            override fun onFailure(
                statusCode: Int, headers: Array<out Header>?,
                responseBody: ByteArray?,
                error: Throwable?
            ) {

            }

        })

    }

    //Mengirimkan data ke favorit
    private fun loadFavorit() {
        val favoritanda = intent.getParcelableExtra<NamaUN>(EXTRA_FAVORIT) as NamaUN
        tv_une.text = favoritanda.username
        Glide.with(this)
            .load(favoritanda.profile_picture)
            .apply(RequestOptions().override(90, 90))
            .into(pp)
    }

    private fun favoritCheck() {
        uriId = Uri.parse(CONTENT_URI.toString() + "/" + detailuser.id)
        val cursor = contentResolver.query(uriId,null,null,null,null)
        val favcheck = MappingHelper.mapCursorToArrayList(cursor)
        for (favorit in favcheck) {
            if (detailuser.id == favorit.id) {
                FavoritAnda = true
            }
        }
    }

    //State hati
    override fun onClick(view: View) {
        val yourFavorit: Int = R.drawable.favor
        val notyourFavorit: Int = R.drawable.favoritkosong

        if (view.id == R.id.fab_favor) {
            if (FavoritAnda) {
                uriWithId = Uri.parse(CONTENT_URI.toString() + "/" + favorit?.id)
                contentResolver.delete(uriWithId, null, null)
                Toast.makeText(this, "Hapus dari favorit", Toast.LENGTH_SHORT).show()
                fab_favor.setImageResource(notyourFavorit)
                FavoritAnda = false
                finish()
            }

            else {
                Toast.makeText(this, "Tambah", Toast.LENGTH_SHORT).show()
                fab_favor.setImageResource(yourFavorit)

                FavoritAnda = true

                val username = tv_une.text.toString()
                val profilepicture = pp.toString()

                val intent = Intent()
                intent.putExtra(EXTRA_FAVORIT, favorit)
                intent.putExtra(EXTRA_POSITION, position)
                val values = ContentValues()
                values.put(USERNAME, detailuser.username)
                values.put(GAMBARPP, detailuser.profile_picture)
                contentResolver.insert(CONTENT_URI, values)

            }

        }

    }
}

Favorit

package com.wibu.picodiploma.submissionakhir.Favorit

import android.app.Activity
import android.content.Intent
import android.database.ContentObserver
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.os.PersistableBundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import com.wibu.picodiploma.submissionakhir.Database.DatabaseContract.FavoritColumns.Companion.CONTENT_URI
import com.wibu.picodiploma.submissionakhir.Detail.DetailuserActivity
import com.wibu.picodiploma.submissionakhir.Main.NamaUN
import com.wibu.picodiploma.submissionakhir.MappingHelper
import com.wibu.picodiploma.submissionakhir.R
import com.wibu.picodiploma.submissionakhir.databinding.ActivityFavoritBinding
import kotlinx.android.synthetic.main.activity_favorit.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

class Favorit : AppCompatActivity() {
    private lateinit var binding: ActivityFavoritBinding

    private val UN = Activity()

    private lateinit var adapter: FavoritAdapter
    private val favoritun = NamaUN()
    private var position: Int = 0
    private lateinit var data : Intent
    private var favorit: NamaUN? = null
    private var FavoritAnda = false
    private lateinit var uriWithId: Uri

    companion object {
        private const val EXTRA_STATE = "extra_state"
        private const val EXTRA_FAVORIT = "extra_favorit"
        private const val EXTRA_POSITION = "extra_position"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_favorit)
        showRecylcer()

        favorit = intent.getParcelableExtra(EXTRA_FAVORIT)
        if (favorit != null) {
            position = intent.getIntExtra(EXTRA_POSITION, 0)

        } else {
            favorit = NamaUN()
        }
        val handlerThread = HandlerThread("DataObserver")
        handlerThread.start()
        val handler = Handler(handlerThread.looper)

        val myObserver = object : ContentObserver(handler) {
            override fun onChange(self: Boolean) {
                loadasync()
            }
        }
        contentResolver.registerContentObserver(CONTENT_URI, true, myObserver)

    }

    private fun showRecylcer() {
        rv_favorit.layoutManager = LinearLayoutManager(this)
        rv_favorit.setHasFixedSize(true)
        adapter = FavoritAdapter(this)
        rv_favorit.adapter = adapter

    }

    private fun loadasync() {
        GlobalScope.launch(Dispatchers.Main) {
            val defferedFavorit = async(Dispatchers.IO) {
                val cursor = contentResolver.query(CONTENT_URI, null, null, null, null)
                MappingHelper.mapCursorToArrayList(cursor)
            }
            val favorit = defferedFavorit.await()
            if (favorit.size > 0) {
                adapter.listFavorit = favorit

            } else {
                adapter.listFavorit = ArrayList()
                snackbar(R.string.no_data)
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
        super.onSaveInstanceState(outState, outPersistentState)
        outState.putParcelableArrayList(EXTRA_STATE, adapter.listFavorit)
    }

    private fun snackbar(message: Int) {
        Snackbar.make(rv_favorit, message, Snackbar.LENGTH_SHORT).show()
    }

    override fun onResume() {
        super.onResume()
        loadasync()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (data != null) {
            when (requestCode) {

                //Delete
                DetailuserActivity.RESULT_DELETE -> {
                    val position = data.getIntExtra(DetailuserActivity.EXTRA_POSITION, 0)

                    adapter.removeItem(position)

                    snackbar(R.string.delete_data)
                }
            }
        }
    }

}

FavoritAdapter

package com.wibu.picodiploma.submissionakhir.Favorit

import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.wibu.picodiploma.submissionakhir.Detail.DetailuserActivity
import com.wibu.picodiploma.submissionakhir.Main.NamaUN
import com.wibu.picodiploma.submissionakhir.R
import com.wibu.picodiploma.submissionakhir.databinding.TempleteFavoritBinding

class FavoritAdapter(private val activity: Activity) : RecyclerView.Adapter<FavoritAdapter.FavoritViewHolder>() {
    private var onItemClickCallback: OnItemClickCallback? = null

    fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
        this.onItemClickCallback = onItemClickCallback
        DetailuserActivity.EXTRA_DETAIL

    }

    var listFavorit = ArrayList<NamaUN>()
        set(listFavorit) {
            if (listFavorit.size >= 0) {
                this.listFavorit.clear()
            }
            this.listFavorit.addAll(listFavorit)

            notifyDataSetChanged()
        }

    fun addItem(favorit: NamaUN) {
        this.listFavorit.add(favorit)
        notifyItemInserted(this.listFavorit.size - 1)
    }

    fun removeItem(position: Int) {
        this.listFavorit.removeAt(position)
        notifyItemRemoved(position)
        notifyItemRangeChanged(position, this.listFavorit.size)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavoritViewHolder {
        val view =
            LayoutInflater.from(parent.context).inflate(R.layout.templete_favorit, parent, false)
        return FavoritViewHolder(view)
    }

    override fun onBindViewHolder(holder: FavoritAdapter.FavoritViewHolder, position: Int) {
        holder.bind(listFavorit[position])
    }

    override fun getItemCount(): Int {
        return this.listFavorit.size
    }

    inner class FavoritViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val bindings = TempleteFavoritBinding.bind(itemView)

        fun bind(favorit: NamaUN) {
            with(bindings) {
                Glide.with(itemView.context)
                    .load(favorit.profile_picture)
                    .apply(RequestOptions().override(55, 55))
                    .into(ppUn)

                bindings.tvUN.text = favorit.username
                itemView.setOnClickListener {
                    onItemClickCallback?.onItemClicked(favorit)

                    rvFavorit.setOnClickListener(
                        CustomOnItemClickListener(
                            adapterPosition,
                            object : CustomOnItemClickListener.OnItemClickCallback {
                                override fun onItemClicked(view: View, position: Int) {
                                    val intent = Intent(activity, DetailuserActivity::class.java)
                                    intent.putExtra(DetailuserActivity.EXTRA_POSITION, position)
                                    intent.putExtra(DetailuserActivity.EXTRA_FAVORIT, favorit)
                                    intent.putExtra(DetailuserActivity.EXTRA_DETAIL, favorit.username)
                                    activity.startActivity(intent)
                                }
                            })
                    )
                }

            }

        }

    }
}

interface  OnItemClickCallback {
    fun onItemClicked(data : NamaUN)
    {

    }

}

DatabaseHelper

package com.wibu.picodiploma.submissionakhir.Database

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import com.wibu.picodiploma.submissionakhir.Database.DatabaseContract.FavoritColumns.Companion.TABLE_NAME

internal class DatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION){

    companion object {

        private const val DATABASE_NAME = "dbfavoritapp"

        private const val DATABASE_VERSION = 1

        private const val SQL_CREATE_FAVORIT = "CREATE TABLE $TABLE_NAME" +
                " (${DatabaseContract.FavoritColumns._ID} INTEGER PRIMARY KEY," +
                " ${DatabaseContract.FavoritColumns.USERNAME} TEXT NOT NULL," +
                " ${DatabaseContract.FavoritColumns.GAMBARPP} TEXT NOT NULL)"

    }

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(SQL_CREATE_FAVORIT)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
        onCreate(db)
    }
}

Mohon bantuannya, terimakasih

avatar samueloliver
@samueloliver

1 Kontribusi 0 Poin

Diperbarui 3 tahun yang lalu

1 Jawaban:

<div>Mungkin bisa di cek berdasarkan username gan, biasanya kan Github usernamenya unik. Jadi saat tambah ke favorite, cek dulu di local db nya apakah sudah ada data dgn username ini? Jika sudah ada maka jangan tambahkan.<br><br>Sedangkan jika belum ada username tersebut di db / sqlite, baru tambahkan.</div>

avatar IfanZalukhu
@IfanZalukhu

217 Kontribusi 158 Poin

Dipost 3 tahun yang lalu

Login untuk ikut Jawaban