RecyclerView 仅在最小化时显示
RecyclerView only shown on minimized
我使用改装从 PHP(localhost) 获取数据作为 JSON 并使用回收器视图显示它。我的问题是,每当我进入全屏(图 1)时,我的数据都不会显示,而每当我最小化应用程序(图 2)时,我的数据就正常了。
Image 1
Image 2
这是我的代码:
Java/Kotlin
网络配置
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>
}
用户表
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
}
}
}
用户数据
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
操作数据库
<?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;
}
}
显示用户
<?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);
感谢您的帮助:)
因为入队是异步的。从回调
获取数据后,您必须调用notifyDataSetChanged
userAdapter?.submitList(userListData)
userAdapter?.notifyDataSetChanged()
或
fun submitList(userList: List<UserData>){
items = userList
notifyDataSetChanged()
}
我使用改装从 PHP(localhost) 获取数据作为 JSON 并使用回收器视图显示它。我的问题是,每当我进入全屏(图 1)时,我的数据都不会显示,而每当我最小化应用程序(图 2)时,我的数据就正常了。
Image 1
Image 2
这是我的代码:
Java/Kotlin
网络配置
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>
}
用户表
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
}
}
}
用户数据
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 操作数据库
<?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;
}
}
显示用户
<?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);
感谢您的帮助:)
因为入队是异步的。从回调
获取数据后,您必须调用notifyDataSetChangeduserAdapter?.submitList(userListData)
userAdapter?.notifyDataSetChanged()
或
fun submitList(userList: List<UserData>){
items = userList
notifyDataSetChanged()
}