英文:
RecylerView not updating new data unless the emulator is refreshed by turning on and off
问题
上下文: 需要为大学构建一个Android应用程序,用于解析来自Rss源的XML数据以获取交通数据。数据获取没有问题。但我试图实现一个下拉选择框,当其更改时,它将从另一个API链接获取新数据。数据获取很正常。
问题: 视图没有更新,除非我按一下模拟器设备(开/关),然后新数据会正确显示。
尝试的解决方案:
我尝试了使用mAdapter.notifyDataSetChanged();
,但我不太确定我哪里出错了。
PS(对Java/Android Studio非常陌生)。 为什么只有在我刷新设备(通过打开和关闭手机)后才会更新呢?
MainActivity.java
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
// ... 其他代码 ...
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
if(text.toLowerCase().equalsIgnoreCase("roadworks")){
this.urlSource = "https://trafficscotland.org/rss/feeds/roadworks.aspx";
} else if(text.toLowerCase().equalsIgnoreCase("Planned Roadworks")){
this.urlSource = "https://trafficscotland.org/rss/feeds/plannedroadworks.aspx";
ArrayList<Item> newList = new ArrayList<>();
try {
obj = new HandleXml(this.urlSource);
newList = obj.fetchXml();
mAdapter.set_data(newList);
} catch (XmlPullParserException e) {
e.printStackTrace();
}
} else {
this.urlSource = "https://trafficscotland.org/rss/feeds/currentincidents.aspx";
Log.i("Url", "Url changed" + this.urlSource);
}
}
}
ItemRecycleAdapter.java
public class ItemRecycleAdapter extends RecyclerView.Adapter<ItemRecycleAdapter.ItemRecyleHolder> implements Filterable {
// ... 其他代码 ...
public void set_data(ArrayList<Item> newList){
if(mArrayList != null){
mArrayList.clear();
mArrayList.addAll(newList);
} else {
mArrayList = new ArrayList<>(newList);
}
notifyDataSetChanged();
}
public void updateData(ArrayList<Item> newList){
this.mArrayList.clear();
this.mArrayList.addAll(newList);
notifyDataSetChanged();
}
// ... 其他代码 ...
}
主要更改和说明:
- 在
MainActivity.java
中,onItemSelected
方法中更改了URL,并通过set_data
方法更新了适配器中的数据。 - 在
ItemRecycleAdapter.java
中,set_data
方法使用了addAll
方法将新数据添加到现有列表中,然后调用notifyDataSetChanged
方法来通知适配器数据已更改。 - 建议使用
addAll
而不是直接赋值,以便在适配器中的数据更改时能够正常更新视图。
英文:
Context: Need to build an android application(for uni) that parses XML data from an Rss feed for traffic data. I am getting data no issues. But I was trying to implement a spinner than when its changed, it will fetch the new data from another API link. The data is getting grabbed fine.
Problem: The view isn't being updated unless I press the emulator device (Off/On) then the new data is shown properly.
Tried Solution:
I have tried using mAdapter.notifyDataSetChanged(); and I'm not quite sure where I am going wrong.
PS(Really new to Java/Android Studio). Any suggestions why its only updating once I refresh the device either by turning the phone on and off.
Main Activity.java
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static final String TAG = "MainActivity";
private static final int ERROR_DIALOG_REQUEST =9001;
private RecyclerView mRecyclerView;
private ItemRecycleAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private EditText search;
private String urlSource = "https://trafficscotland.org/rss/feeds/roadworks.aspx";
private HandleXml obj;
private ListView listView;
private Calendar cal = Calendar.getInstance();
private SimpleDateFormat sdf= new SimpleDateFormat("MMM-dd-yyyy");
private String current_date = sdf.format(cal.getTime());
private DatePicker datePicker;
private Button sbmt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = findViewById(R.id.feedType);
search = (TextInputEditText)findViewById(R.id.inputDate);
search.setText(current_date);
mRecyclerView = findViewById(R.id.recView);
obj = new HandleXml(this.urlSource);
try {
mAdapter = new ItemRecycleAdapter(obj.fetchXml());
} catch (XmlPullParserException e) {
e.printStackTrace();
}
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
BottomNavigationView bottomnav = findViewById(R.id.bottom_navigation);
bottomnav.setOnNavigationItemSelectedListener(navListener);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.feedValues, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
if(isMapOK()){
Log.i("fine", "MAP IS OKAY");
init();
}
}
ItemRecycleAdapter.java
public class ItemRecycleAdapter extends RecyclerView.Adapter<ItemRecycleAdapter.ItemRecyleHolder> implements Filterable {
private ArrayList<Item> mArrayList;
private ArrayList<Item> mArrayListCopy;
@Override
public Filter getFilter() {
return itemFilter;
}
public static class ItemRecyleHolder extends RecyclerView.ViewHolder{
public TextView title;
public TextView desc;
public TextView pubDate;
public ItemRecyleHolder(@NonNull View itemView) {
super(itemView);
title =itemView.findViewById(R.id.title);
desc =itemView.findViewById(R.id.desc);
pubDate =itemView.findViewById(R.id.pubDate);
}
}
public ItemRecycleAdapter(ArrayList<Item> itemList){
this.mArrayList = itemList;
this.mArrayListCopy = itemList;
notifyDataSetChanged();
}
public void set_data(ArrayList<Item>newList){
if(mArrayList != null){
mArrayList.clear();
mArrayList = newList;
}else{
mArrayList = newList;
}
// notifyDataSetChanged();
}
public void updateData(ArrayList<Item> newList){
this.mArrayList.clear();
this.mArrayList = newList;
//notifyDataSetChanged();
}
@NonNull
@Override
public ItemRecyleHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_view_layout, parent, false);
ItemRecyleHolder irh = new ItemRecyleHolder(v);
return irh;
}
@Override
public void onBindViewHolder(@NonNull ItemRecyleHolder holder, int position) {
Item currentItem = mArrayList.get(position);
holder.title.setText(currentItem.getTitle());
holder.desc.setText(currentItem.getDescription());
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
holder.pubDate.setText(sdf.format(currentItem.getPublishDate()));
}
@Override
public int getItemCount() {
return mArrayList.size();
}
onItemSelected (testing with one option in the spinner, in MainActivity)
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
//this.urlSource = text;
if(text.toLowerCase().equalsIgnoreCase("roadworks")){
this.urlSource = "https://trafficscotland.org/rss/feeds/roadworks.aspx";
//Log.i("Url", "Url changed" + this.urlSource);
}else if(text.toLowerCase().equalsIgnoreCase("Planned Roadworks")){
this.urlSource = "https://trafficscotland.org/rss/feeds/plannedroadworks.aspx";
ArrayList<Item> newList = new ArrayList<>();
try {
obj = new HandleXml(this.urlSource);
newList = obj.fetchXml();
mAdapter.set_data(newList);
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}else{
this.urlSource = "https://trafficscotland.org/rss/feeds/currentincidents.aspx";
Log.i("Url", "Url changed" + this.urlSource);
}
}
答案1
得分: 0
在onItemSelected尝试这样做:
obj = new HandleXml(this.urlSource);
mAdapter = null;
try {
mAdapter = new ItemRecycleAdapter(obj.fetchXml());
} catch (XmlPullParserException e) {
e.printStackTrace();
}
if (mAdapter != null)
mRecyclerview.setAdapter(mAdapter);
英文:
In onItemSelected try this
obj = new HandleXml(this.urlSource);
mAdapter = null;
try {
mAdapter = new ItemRecycleAdapter(obj.fetchXml());
} catch (XmlPullParserException e) {
e.printStackTrace();
}
if(mAdapter ! = null)
mRecyclerview.setAdapter(mAdapter)
专注分享java语言的经验与见解,让所有开发者获益!
评论