所以我试图将Parse数据库查询中的数据加载到recyclerView中。查询将我的所有数据完美地加载到我的ArrayList中,然后将其添加到我的适配器中。
不幸的是,我的recyclerView只显示适配器数据的最后一个添加内容。但是,如果适配器中有15个对象,则最后一次添加将在屏幕上重复15次。
我认为问题在于,由于某种原因,数据ArrayList内部的值不存在于查询之外,即使我在类中声明它。
这是我的MainActivity代码:
public class MainActivity extends ActionBarActivity implements DataAdapter.ClickListener {
private RecyclerView recyclerView;
static DataAdapter adapter;
public TextView tvParseUser;
private Context context;
String currentUser;
Data current = new Data();
List<Data> data = new ArrayList<>();
public static String BROADCAST_ACTION =
"broadcast_action_packagename";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(br, filter);
//testing Sree's suggestion
adapter = new CommitmentDataAdapter(getApplicationContext(), data);
Log.d("DATABEFOREADD", data.toString()); //data here is empty
startService(new Intent(this, Broadcast_Service.class));
tvParseUser = (TextView) findViewById(R.id.ParseUserName);
setContentView(R.layout.activity_main);
ParseQuery<ParseObject> query = ParseQuery.getQuery("ColumnTitle");
query.whereEqualTo("author", ParseUser.getCurrentUser());
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
query.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> list, ParseException e) { //returns actual Parse Object
if (e == null)
{
for (ParseObject getData : list)
{
current.1= getData.getString("1");
current.2= getData.getString("2");
current.3= getData.getString("3");
current.4= getData.getString("4");
current.5= getData.getString("5");
current.combined= current.1 + current.2 + current.3 + current.4;
//checked Log.d, query is working fine. ArrayList should have an object of all the data for use
data.add(current);
Log.d("data", data.toString());
Log.d("CurrentCombined", current.combined);
adapter.notifyDataSetChanged(); //Sree's suggestion
//data correctly contains list of objects that I need
}
Log.d("dataInfo", String.valueOf(data));
Log.d("Current", current.toString());
}
else
{
}
recyclerView.setAdapter(adapter); //set recyclerView to this adapter
}
});
Log.d("ADAPTERDATA", data.toString()); //NOTE THIS RETURNS AN EMPTY ARRAY. WHY?!
}
public BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent);
adapter.notifyDataSetChanged();
}
};
DataAdapter代码:
package com.example.android.moneyspeaks;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.slf4j.helpers.Util;
import org.w3c.dom.Text;
import java.sql.Time;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.MyViewHolder> {
List<Data> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
private ClickListener clickListener;
long millisCountDownTime;
Intent intent;
PendingIntent pendingIntent;
Thread thread;
Handler handler;
Long now;
Long later;
Integer i = 0;
final Handler myHandler = new Handler();
public DataAdapter(Context context, List<Data> data)
{
inflater = LayoutInflater.from(context);
this.data = data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = inflater.inflate(R.layout.recycler_view_layout, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
public void setClickListener(ClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Data current = data.get(position);
holder.combined.setText(current.combined);
holder.codeTimer.setText(current.goalTimer);
holder.submitCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "HELL YA", Toast.LENGTH_LONG).show();
}
});
if (current.classify2.equals("day(s)")) {
millisCountDownTime = 86400000;
} else if (current.classify2.equals("week(s)")) {
millisCountDownTime = 604800000;
} else if (current.classify2.equals("hour(s)")) {
millisCountDownTime = 3600000;
} else if (current.classify2.equals("minute(s)")) {
millisCountDownTime = 6000;
}
final Runnable myRunnable = new Runnable() {
@Override
public void run() {
holder.codeTimer.setText(String.valueOf(i));
}
};
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView combined;
TextView enterCode;
TextView codeTimer;
EditText codeInputField;
Button submitCode;
public MyViewHolder(View itemView) {
super(itemView);
combined= (TextView) itemView.findViewById(R.id.combinedSentence);
codeTimer = (TextView) itemView.findViewById(R.id.codeTimer);
submitCode = (Button) itemView.findViewById(R.id.submitTheCode);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.submitTheCode) {
Intent i = new Intent(v.getContext(), Different.class);
v.getContext().startActivity(i);
}
}
});
}
}
public interface ClickListener {
public void itemClicked(View view, int position);
}
}
答案 0 :(得分:2)
我也面临同样的问题,并打破了我的头谷歌搜索..
绝对解决方案是在主要活动的for循环中创建current
类型Data
对象
说明:当您在循环外声明current
对象时,您正在创建单个对象并使用具有相同值的相同对象
快乐的编码!!
答案 1 :(得分:0)
我认为是因为你在初始化适配器之前调用了adapter.notifyDataSetChanged()。因为它只是在回调上初始化,我认为你可能有可能在回调完成之前调用notifyDataSetChanged()(我想你提到广播每秒都会发生)。我无法100%确定,因为我无法看到您的其余代码。
答案 2 :(得分:0)
所以,让我直截了当。您在onCreate()中执行以下操作:
因此,您希望在执行3中的代码和基本上下一组4中的代码指令之间,Android将在另一个CPU上安排该进程,运行完成,将该数据编组到由UI线程,所有的及时,以便当它执行4的代码时,有实际的数据?你有一个特殊的手机,其中UI线程运行在一个速度慢100倍的核心?
没有。线程同步问题没有灵丹妙药。要么重新设计代码,以便跨线程访问数据正确同步,要么使用强制执行所需行为的线程同步原语。