I use retrofit to get data from PHP(localhost) as JSON and display it with recycler view. My problem is my data never show whenever I go fullscreen(Image 1) and goes normal whenever I minimized the app(Image 2).
Image 1
Image 2
Here is My Code:
Java/Kotlin
NetworkConfig
package com.example.simplemysqlproject import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import com.google.gson.JsonObject import org.json.JSONObject import retrofit2.Call import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.http.GET import retrofit2.http.POST class NetworkConfig { // set interceptor fun getInterceptor() : OkHttpClient { val logging = HttpLoggingInterceptor() logging.level = HttpLoggingInterceptor.Level.BODY val okHttpClient = OkHttpClient.Builder() .addInterceptor(logging) .build() return okHttpClient } fun getRetrofit() : Retrofit { return Retrofit.Builder() .baseUrl(Constants.Root_URL) .client(getInterceptor()) .addConverterFactory(GsonConverterFactory.create()) .build() } fun getService() = getRetrofit().create(Users::class.java) } interface Users { @POST("ShowUser.php/") fun getUsers(): Call<JsonObject> }
UserTable
package com.example.simplemysqlproject import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.android.volley.Request import com.android.volley.toolbox.StringRequest import com.android.volley.toolbox.Volley import com.google.gson.JsonArray import org.json.JSONException import com.google.gson.JsonObject import org.json.JSONObject import retrofit2.Call import retrofit2.Callback import retrofit2.Response import java.util.* class UserTable : AppCompatActivity() { private lateinit var rv: RecyclerView private var userAdapter:UserRVAdapter?=null private var userListData:MutableList<UserData> = ArrayList() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.read_user) initRecyclerView(); showRetro(); userAdapter?.notifyDataSetChanged() } private fun showRetro(){ var jsonObject:Callback<JsonObject>?=null NetworkConfig().getService() .getUsers() .enqueue(object :Callback<JsonObject>{ override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) { var jsonArray=response.body()?.getAsJsonArray("data") var b:Int=0 for(i in 0..(jsonArray?.size()?.minus(1)!!)){ userListData.add(UserData(jsonArray?.get(i)?.asJsonObject?.get("id")?. asInt,jsonArray?.get(i)?.asJsonObject?.get("Username")?.asString, jsonArray?.get(i)?.asJsonObject?.get("email")?.asString)) } Toast.makeText(this@UserTable, response.body()?.get("message").toString().trim(), Toast.LENGTH_LONG).show() userAdapter?.submitList(userListData) } override fun onFailure(call: Call<JsonObject>, t: Throwable) { Toast.makeText(this@UserTable, t.localizedMessage, Toast.LENGTH_LONG).show() } }) } private fun addDataSet() { var stringRequest=StringRequest(Request.Method.POST, Constants.ShowAll_URL, com.android.volley.Response.Listener<String> { response -> try { var jsonObject: org.json.JSONObject = org.json.JSONObject(response) var jsonArray = jsonObject.getJSONArray("data") for (a in 0 until jsonArray.length()) { var b: org.json.JSONObject = jsonArray.getJSONObject(a) userListData.add(UserData(b.getInt("id"), b.getString("Username"), b.getString("email"))) userAdapter?.submitList(userListData) } } catch (e: JSONException) { e.printStackTrace() } }, com.android.volley.Response.ErrorListener { } ) var reqQueue=Volley.newRequestQueue(this@UserTable) reqQueue.add(stringRequest) } private fun initRecyclerView() { rv=findViewById<RecyclerView>(R.id.recycler_view) rv.apply { layoutManager=LinearLayoutManager(this@UserTable) userAdapter=UserRVAdapter() adapter=userAdapter } } }
UserData
package com.example.simplemysqlproject data class UserData( var id: Int?, var username: String?, var email: String? )
UserRVAdapter
package com.example.simplemysqlproject import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.request.RequestOptions import java.util.* class UserRVAdapter:RecyclerView.Adapter<RecyclerView.ViewHolder>(){ private val TAG: String = "AppDebug" private var items: List<UserData> = ArrayList() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return BlogViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.user_data, parent, false) ) } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when(holder) { is BlogViewHolder -> { holder.bind(items.get(position)) } } } override fun getItemCount(): Int { return items.size } fun submitList(userList: List<UserData>){ items = userList } class BlogViewHolder constructor( itemView: View ): RecyclerView.ViewHolder(itemView){ val username:TextView = itemView.findViewById(R.id.tvUsername) val email:TextView = itemView.findViewById(R.id.tvEmail) fun bind(userdata: UserData){ /* val requestOptions = RequestOptions() .placeholder(R.drawable.ic_launcher_background) .error(R.drawable.ic_launcher_background) */ /* Glide.with(itemView.context) .applyDefaultRequestOptions(requestOptions) .load(blogPost.image) .into(blog_image) */ username.setText(userdata.username) email.setText(userdata.email) } } }
XML
read_user
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recycler_view" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
user_data
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" app:cardElevation="10dp" app:cardCornerRadius="2dp" app:cardPreventCornerOverlap="false" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tvUsername" android:text="Username" android:textColor="#000" android:textSize="19sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tvEmail" android:text="Email" android:textSize="19sp" android:layout_marginTop="10dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_gravity="center" android:gravity="center" android:layout_height="wrap_content"> <ImageButton android:layout_width="50dp" android:layout_height="50dp" app:srcCompat="@drawable/edit" android:id="@+id/imageButton" android:tint="@color/purple_700" /> <ImageButton android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" app:srcCompat="@drawable/wrong" android:id="@+id/wrongButton" android:tint="@color/colorAccent" /> </LinearLayout> </androidx.cardview.widget.CardView>
PHP operationDB
<?php class OperationDB{ private $con; function __construct(){ require_once dirname(__FILE__).'/ConnectDB.php'; $db= new ConnectDB(); $this->con= $db->connect(); } public function CreateUser($username,$password,$email){ if($this->isUserExist($username,$email)){ return 0; } else { $pass=md5($password); $CreateQuery=$this->con->prepare("INSERT INTO `user data` (`id`, `Username`,`Password`,`Email`) VALUES (NULL,?,?,?);"); $CreateQuery->bind_param("sss",$username,$pass,$email); if($CreateQuery->execute()){ return 1; } else{ return 2; } } } public function ShowAll(){ $sql="SELECT id,Username,email FROM `user data`;"; $result=mysqli_query($this->con,$sql); return $result; } public function LoginUser($username,$password){ $pass=md5($password); $LoginQuery=$this->con->prepare("SELECT id FROM `user data` WHERE username=? AND password=?"); $LoginQuery->bind_param("ss",$username, $pass); $LoginQuery->execute(); $LoginQuery->store_result(); return $LoginQuery->num_rows>0; } public function DeleteUser($id){ $DeleteQuery=$this->con->prepare("DELETE from `user data` where id=?"); $DeleteQuery->bind_param("i",$id); } private function isUserExist($username,$email){ $CheckQuery=$this->con->prepare("SELECT id FROM `user data` WHERE username=? or email=?"); $CheckQuery->bind_param("ss",$username,$email); $CheckQuery->execute(); $CheckQuery->store_result(); return $CheckQuery->num_rows>0; } }
ShowUser
<?php require_once '../includes/OperationDB.php'; $response=array(); $dataArray=array(); if($_SERVER['REQUEST_METHOD']=='POST'){ $db=new OperationDB(); if($OperationResult=$db->ShowAll()){ while($row=mysqli_fetch_assoc($OperationResult)){ $dataArray[]=$row; } $response['data']=$dataArray; $response['error']=false; $response['message']="Showing Data!"; } else{ $response['error']=true; $response['message']="Showing failed!"; } } else{ $response['error']=true; $response['message']="Invalid Request Bro"; } echo json_encode($response);
Thank you for your help 🙂
Advertisement
Answer
Because enqueue is asynchronously. You have to call notifyDataSetChanged after get data from callback
userAdapter?.submitList(userListData) userAdapter?.notifyDataSetChanged()
or
fun submitList(userList: List<UserData>){ items = userList notifyDataSetChanged() }