我正在尝试显示从Mysql
到RecylerView
的数据库,但应用程序未显示任何内容。 logcat中没有error
。我从Google获得了本教程,并且原始Project正常工作。我只是学习在代码中实现。
build.gradle:
implementation "androidx.recyclerview:recyclerview-selection:1.1.0-beta01"
implementation 'com.android.volley:volley:1.1.1'
implementation 'com.github.bumptech.glide:glide:4.8.0'
这是activity_main.xml的XML代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.example.skripsans.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recylcerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="745dp"
tools:layout_editor_absoluteY="-51dp"
android:visibility="visible">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
product_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="90dp"
android:padding="4dp" />
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/imageView"
android:text="Apple MacBook Air Core i5 5th Gen - (8 GB/128 GB SSD/Mac OS Sierra)"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
android:textColor="#000000" />
<TextView
android:id="@+id/textViewShortDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewTitle"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:text="13.3 Inch, 256 GB"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small" />
<TextView
android:id="@+id/textViewRating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewShortDesc"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:background="@color/colorPrimary"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="4.7"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small.Inverse"
android:textStyle="bold" />
<TextView
android:id="@+id/textViewPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewRating"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:text="INR 56990"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
Product.java
package com.example.skripsans;
/**
* Created by Belal on 10/18/2017.
*/
public class Product {
private int id;
private String title;
private String shortdesc;
private double rating;
private double price;
private String image;
public Product(int id, String title, String shortdesc, double rating, double price, String image) {
this.id = id;
this.title = title;
this.shortdesc = shortdesc;
this.rating = rating;
this.price = price;
this.image = image;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getShortdesc() {
return shortdesc;
}
public double getRating() {
return rating;
}
public double getPrice() {
return price;
}
public String getImage() {
return image;
}
}
ProductsAdapter.java
package com.example.skripsans;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* Created by Belal on 10/18/2017.
*/
public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ProductViewHolder> {
private Context mCtx;
private List<Product> productList;
public ProductsAdapter(Context mCtx, List<Product> productList) {
this.mCtx = mCtx;
this.productList = productList;
}
@Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.product_list, null);
return new ProductViewHolder(view);
}
@Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
Product product = productList.get(position);
//loading the image
Glide.with(mCtx)
.load(product.getImage())
.into(holder.imageView);
holder.textViewTitle.setText(product.getTitle());
holder.textViewShortDesc.setText(product.getShortdesc());
holder.textViewRating.setText(String.valueOf(product.getRating()));
holder.textViewPrice.setText(String.valueOf(product.getPrice()));
}
@Override
public int getItemCount() {
return productList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
TextView textViewTitle, textViewShortDesc, textViewRating, textViewPrice;
ImageView imageView;
public ProductViewHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.textViewTitle);
textViewShortDesc = itemView.findViewById(R.id.textViewShortDesc);
textViewRating = itemView.findViewById(R.id.textViewRating);
textViewPrice = itemView.findViewById(R.id.textViewPrice);
imageView = itemView.findViewById(R.id.imageView);
}
}
}
MainActivity.java
package com.example.skripsans;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//this is the JSON Data URL
//make sure you are using the correct ip else it will not work
private static final String URL_PRODUCTS = "http://192.168.100.10/Api.php";
//a list to store all the products
List<Product> productList;
//the recyclerview
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//getting the recyclerview from xml
recyclerView = findViewById(R.id.recylcerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//initializing the productlist
productList = new ArrayList<>();
//this method will fetch and parse json
//to display it in recyclerview
loadProducts();
}
private void loadProducts() {
/*
* Creating a String Request
* The request type is GET defined by first parameter
* The URL is defined in the second parameter
* Then we have a Response Listener and a Error Listener
* In response listener we will get the JSON response as a String
* */
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL_PRODUCTS,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONArray array = new JSONArray(response);
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject product = array.getJSONObject(i);
//adding the product to product list
productList.add(new Product(
product.getInt("id"),
product.getString("title"),
product.getString("shortdesc"),
product.getDouble("rating"),
product.getDouble("price"),
product.getString("image")
));
}
//creating adapter object and setting it to recyclerview
ProductsAdapter adapter = new ProductsAdapter(MainActivity.this, productList);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//adding our stringrequest to queue
Volley.newRequestQueue(this).add(stringRequest);
}
}
答案 0 :(得分:0)
这是因为您将根布局和后续子元素的高度设置为 wrap_content
。如果你给你的根布局高度和它下面的每个视图给包装内容的最里面的视图一个明确的大小,你应该看到内容。我目前正在处理同样的问题,这导致我来到这里。到目前为止,我用来显示需要在回收器中包裹高度的子视图的最佳解决方案是通过将新的 LayoutParams 传递给我包裹在我的适配器 OnBindViewHolder()
中的视图来进行一些不确定的数学和大小调整。
发生这种情况是因为视图在其内容设置在 OnBindViewHolder()
之前没有大小,但是当您到达那里时您的视图已经膨胀,因此布局管理器测量了wrapped 的空元素的高度高度为 0
,适配器会膨胀视图,然后继续在 OnBindViewHolder()
中设置它们的内容,这不会触发重新绘制。如果您的回收器中有足够多的子视图可以将它们滚动到屏幕外,那么它们在滚动回视图时也可能会适当地重新绘制,因为它们现在有内容并因此测量了高度。
我已经看到一些自定义布局管理器覆盖了 getMeasuredHeight 方法等,但没有这样的解决方案对我有用,我最终在 viewHolder 中设置了我的内容数据,然后在视图上调用 .measure()
现在有内容和高度。之后,我将所有元素的布局参数设置为 wrap_content
作为其高度来自一组布局参数,这些布局参数从设置和重新测量数据的最里面的视图中获取 .getMeasuredHeight()
。
如果您确实需要包装高度,此解决方案也可能对您有用,但它有点复杂,并且在我的实现中容易出现错误,因为我包装的最里面的视图是一个行数未知的 TextView直到它被设置。我使用一些简单的数学计算输入字符串将占用多少行,然后乘以 TextView 的度量高度。这是粗略的做法,因为不同屏幕比例、大小和字体的不同设备可能导致 TextView 中不同数量的行,这是不可能在所有设备上都考虑到的。不太复杂的视图可能适合这个解决方案,但使用 GeometryReader 或类似的可以改进它。我今天才开始在我的项目中处理这个问题,所以我还没有真正有机会将其清除,我只是将它设置为可用于我的测试设备的状态,这样我就可以继续研究周围的功能,这将更容易测试我的回收器的完整版本。我需要获取负责制作这些回收器所填充数据的部件,以便我可以对可能的数据和用户设备进行测试变体,然后我可以找到更好的解决方案或微调该解决方案以满足我的需求。< /p>