英文:
Error "RecyclerView: No adapter attached; skipping layout"
问题
以下是您提供的代码部分的翻译:
MainActivity.java
public class MainActivity extends AppCompatActivity {
// ... (其他部分省略)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
Read_network_state(cm);
loadingIndicator = findViewById(R.id.loading_indicator);
emptyView = findViewById(R.id.empty_view);
mRecycleView = this.findViewById(R.id.recycle_list);
mRecycleView.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(this);
mRecycleView.setLayoutManager(manager);
mEarthquake = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
if (isConnected) {
Uri uri = Uri.parse(USS_REQUEST_URL);
Uri.Builder builder = uri.buildUpon();
parseEarthquake(builder.toString());
}
}
// ... (其他部分省略)
}
EarthquakeAdapter.java
public class EarthquakeAdapter extends RecyclerView.Adapter<EarthquakeAdapter.MyViewHolder> {
// ... (其他部分省略)
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
LayoutInflater inflater = LayoutInflater.from(mContext);
view = inflater.inflate(R.layout.earthquake_raw, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int i) {
Earthquake earthquake = mData.get(i);
double earthquakeMagnitude = earthquake.getMagnitude();
DecimalFormat decimalFormat = new DecimalFormat("0.0");
String formattedMagnitude = decimalFormat.format(earthquakeMagnitude);
holder.tvMagnitude.setText(formattedMagnitude);
Date dateObject = new Date(earthquake.getTimeInMilliseconds());
String formattedDate = formatDate(dateObject);
holder.tvDate.setText(formattedDate);
String formattedTime = formatTime(dateObject);
holder.tvTime.setText(formattedTime);
// ... (其他部分省略)
}
// ... (其他部分省略)
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAppearance="?android:textAppearanceMedium"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycle_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:listitem="@layout/earthquake_raw"/>
<ProgressBar
android:id="@+id/loading_indicator"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
earthquake_raw.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="150dp"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:paddingEnd="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/magnitude"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:background="@drawable/magnitude_circle"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="16sp"
tools:text="8.9" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/location_offset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:textAllCaps="true"
android:textColor="@android:color/black"
android:textSize="12sp"
tools:text="30km S of" />
<TextView
android:id="@+id/primary_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@android:color/black"
android:textSize="12sp"
tools:text="Long placeholder that should wrap to more than 2 lines of text" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="@color/textColorEarthquakeDetails"
android:textSize="12sp"
tools:text="Mar 6, 2010" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="@color/textColorEarthquakeDetails"
android:textSize="12sp"
tools:text="3:00 PM" />
</LinearLayout>
</LinearLayout>
以上是您提供的代码的翻译部分。如有其他问题或需要进一步帮助,请随时提问。
英文:
I am getting the following error: "RecyclerView: No adapter attached; skipping layout" but I have attached the adapter... I have tried many different ways but I couldn't solve the error.
I am using Volley library to get data. When I launch the activity, only the progress bar is visible until the end, and I receive the Logcat message above. I have added the Recycleview
with the adapter in the MainActivity
. Could you please help me?
Here is my code:
MainActivity
public class MainActivity extends AppCompatActivity {
private RequestQueue mRequestQueue;
private ArrayList<Earthquake> mEarthquake;
private RecyclerView mRecycleView;
private EarthquakeAdapter adapter;
boolean isConnected;
TextView emptyView;
ProgressBar loadingIndicator;
private static final String USS_REQUEST_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
Read_network_state(cm);
loadingIndicator = findViewById(R.id.loading_indicator);
emptyView = findViewById(R.id.empty_view);
mRecycleView = this.findViewById(R.id.recycle_list);
mRecycleView.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(this);
mRecycleView.setLayoutManager(manager);
mEarthquake = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
if (isConnected) {
Uri uri = Uri.parse(USS_REQUEST_URL);
Uri.Builder buider = uri.buildUpon();
parseEarthquake(buider.toString());
}
}
private void parseEarthquake(String key) {
final JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, key.toString(), null, response -> {
double magnitude = Double.parseDouble("");
String location = "";
long time = Long.parseLong("");
String url = "";
try {
JSONArray feature = response.getJSONArray("feature");
for (int i = 0; i < feature.length(); i++) {
JSONObject features = feature.getJSONObject(i);
JSONObject properties = features.getJSONObject("properties");
magnitude = properties.getDouble("mag");
location = properties.getString("place");
time = properties.getLong("time");
url = properties.getString("url");
}
Earthquake earthquake = new Earthquake(magnitude, location, time, url);
mEarthquake.add(earthquake);
adapter = new EarthquakeAdapter(MainActivity.this, mEarthquake);
mRecycleView.setAdapter(adapter);
Log.d("Ruhul", "No adapter");
} catch (JSONException e) {
e.printStackTrace();
}
}, error -> {
// Nothing
});
mRequestQueue.add(request);
}
public void Read_network_state(ConnectivityManager connectivityManager) {
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
if (activeNetwork != null && activeNetwork.isConnectedOrConnecting()) {
isConnected = true;
Log.d("Ruhul", "CONNECTED TO INTERNET");
} else {
isConnected = false;
}
}
}
EarthquakeAdapter
public class EarthquakeAdapter extends RecyclerView.Adapter<EarthquakeAdapter.MyViewHolder> {
private Context mContext;
private List<Earthquake> mData;
public EarthquakeAdapter(Context mContext, List<Earthquake> mData) {
this.mContext = mContext;
this.mData = mData;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
LayoutInflater inflater = LayoutInflater.from(mContext);
view = inflater.inflate(R.layout.earthquake_raw, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int i) {
Earthquake earthquake = mData.get(i);
double earthquakeMagnitude = earthquake.getMagnitude();
DecimalFormat decimalFormat = new DecimalFormat("0.0");
String formattedMagnitude = decimalFormat.format(earthquakeMagnitude);
holder.tvMagnitude.setText(formattedMagnitude);
Date dateObject = new Date(earthquake.getTimeInMilliseconds());
String formattedDate = formatDate(dateObject);
holder.tvDate.setText(formattedDate);
String formattedTime = formatTime(dateObject);
holder.tvTime.setText(formattedTime);
String originalLocation = earthquake.getLocation();
holder.magnitudeCircle = (GradientDrawable) holder.tvMagnitude.getBackground();
int magnitudecolor = getMagnitudeColor(earthquake.getMagnitude());
holder.magnitudeCircle.setColor(magnitudecolor);
if (originalLocation.contains("of")) {
String[] parts = originalLocation.split("of");
holder.tvLocationOffSet.setText(parts[0] + "of");
holder.tvPrimaryLocation.setText(parts[1]);
} else {
holder.tvLocationOffSet.setText("Near The");
holder.tvPrimaryLocation.setText(originalLocation);
}
}
@Override
public int getItemCount() {
return mData.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvMagnitude, tvLocationOffSet, tvPrimaryLocation, tvDate, tvTime;
LinearLayout container;
GradientDrawable magnitudeCircle;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvMagnitude = itemView.findViewById(R.id.magnitude);
tvLocationOffSet = itemView.findViewById(R.id.location_offset);
tvPrimaryLocation = itemView.findViewById(R.id.primary_location);
tvDate = itemView.findViewById(R.id.date);
tvTime = itemView.findViewById(R.id.time);
container = itemView.findViewById(R.id.container);
}
}
/**
* Return the color of the magitude circle based on the intensity of the earthquake.
*
* @param magnitude of the earthquake
*/
private int getMagnitudeColor(double magnitude) {
int magnitudeColorResourceId;
int magnitudeFloor = (int) Math.floor(magnitude);
switch (magnitudeFloor) {
case 0:
case 1:
magnitudeColorResourceId = R.color.magnitude1;
break;
case 2:
magnitudeColorResourceId = R.color.magnitude2;
break;
case 3:
magnitudeColorResourceId = R.color.magnitude3;
break;
case 4:
magnitudeColorResourceId = R.color.magnitude4;
break;
case 5:
magnitudeColorResourceId = R.color.magnitude5;
break;
case 6:
magnitudeColorResourceId = R.color.magnitude6;
break;
case 7:
magnitudeColorResourceId = R.color.magnitude7;
break;
case 8:
magnitudeColorResourceId = R.color.magnitude8;
break;
case 9:
magnitudeColorResourceId = R.color.magnitude9;
break;
default:
magnitudeColorResourceId = R.color.magnitude10plus;
break;
}
return ContextCompat.getColor(mContext, magnitudeColorResourceId);
}
private String formatDate(Date dateObject) {
SimpleDateFormat dateFormat = new SimpleDateFormat("LLL dd, yyyy");
return dateFormat.format(dateObject);
}
private String formatTime(Date dateObject) {
SimpleDateFormat timeFormat = new SimpleDateFormat("h:mm a");
return timeFormat.format(dateObject);
}
}
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAppearance="?android:textAppearanceMedium"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycle_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:listitem="@layout/earthquake_raw"/>
<ProgressBar
android:id="@+id/loading_indicator"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
EarthquakeRaw.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="150dp"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:paddingEnd="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/magnitude"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:background="@drawable/magnitude_circle"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="16sp"
tools:text="8.9" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/location_offset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:textAllCaps="true"
android:textColor="@android:color/black"
android:textSize="12sp"
tools:text="30km S of" />
<TextView
android:id="@+id/primary_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@android:color/black"
android:textSize="12sp"
tools:text="Long placeholder that should wrap to more than 2 line of text" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="@color/textColorEarthquakeDetails"
android:textSize="12sp"
tools:text="Mar 6, 2010" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="@color/textColorEarthquakeDetails"
android:textSize="12sp"
tools:text="3:00 PM" />
</LinearLayout>
</LinearLayout>
答案1
得分: 1
始终尝试在主 UI 线程中连接适配器,或者在异步任务之外进行连接。
此外,您可以在 onCreate()
中添加此代码。当 mEarthquake
数组列表被填充时,调用 adapter.notifyDataSetChanged()
。
adapter = new EarthquakeAdapter(MainActivity.this, mEarthquake);
mRecyclerView.setAdapter(adapter);
英文:
Always try to attach the adapter in main UI thread, or outside your asynchronous task.
Also, you can add this code in oncreate()
. and when mEarthquake
arraylist is populated, call adapter.notifydatasetchanged()
.
adapter = new EarthquakeAdapter(MainActivity.this, mEarthquake);
mRecycleView.setAdapter(adapter);
答案2
得分: 0
你应该在循环内部向模型添加数据。
尝试以下方式会正常工作:
JSONArray feature = response.getJSONArray("feature");
for (int i = 0; i < feature.length(); i++) {
JSONObject features = feature.getJSONObject(i);
JSONObject properties = features.getJSONObject("properties");
magnitude = properties.getDouble("mag");
location = properties.getString("place");
time = properties.getLong("time");
url = properties.getString("url");
Earthquake earthquake = new Earthquake(magnitude, location, time, url);
mEarthquake.add(earthquake);
adapter = new EarthquakeAdapter(MainActivity.this, mEarthquake);
mRecycleView.setAdapter(adapter);
adapter.notifyDatasetChanged();
}
英文:
You should add data to model inside for loop.
Try like below will work fine,
JSONArray feature = response.getJSONArray("feature");
for (int i = 0; i < feature.length(); i++) {
JSONObject features = feature.getJSONObject(i);
JSONObject properties = features.getJSONObject("properties");
magnitude = properties.getDouble("mag");
location = properties.getString("place");
time = properties.getLong("time");
url = properties.getString("url");
Earthquake earthquake = new Earthquake(magnitude, location, time, url);
mEarthquake.add(earthquake);
adapter = new EarthquakeAdapter(MainActivity.this, mEarthquake);
mRecycleView.setAdapter(adapter);
adapter.notifyDatasetChanged();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论