我必须创建一个RecyclerView
,该AsyncTask
每次由我的RecyclerView
创建新项目时都会更新。因此notifyDataSetChanged()
逐渐建立起来。
生成每个项目,然后线程休眠一段时间以查看进度变慢。
我试图获取适配器并用MainActivity
更新它,但是它不能像这样工作。我得到的错误是:
只有创建视图层次结构的原始线程才能触摸其 视图。
另一个想法是使用接口更新我的public class MainActivity extends AppCompatActivity implements ListAdapter.Listener{
static RecyclerView recyclerView;
static ListAdapter adapter;
@Override
public void click(String name) {
if(getResources().getConfiguration().orientation== Configuration.ORIENTATION_LANDSCAPE){
DetailsFragment detailsFragment = (DetailsFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_details);
detailsFragment.setData(name);
}
else{
Toast.makeText(this, "clicked", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, DetailsActivity.class);
intent.putExtra("sorte_name", name);
startActivity(intent);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerView();
new DataContainer().execute();
}
private void initRecyclerView(){
recyclerView = findViewById(R.id.meinRecyclerView);
adapter = new ListAdapter(this, DataContainer.meineSortenListe, this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
中的适配器。但是我不知道该怎么做。首先,我必须知道使用接口的正确方法,还是针对我的问题是否有更好的方法,或者真的很简单的解决方案。
public class DataContainer extends AsyncTask<Void, Void, Void> {
public static ArrayList<String> meineSortenListe = new ArrayList<String>();
ListAdapter myAdapter;
@Override
protected void onPreExecute() {
myAdapter =(ListAdapter)MainActivity.recyclerView.getAdapter();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
for(int i= 0; i<50; i++){
meineSortenListe.add("Sorte "+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
onProgressUpdate();
}
Log.i("info", "array befüllt");
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
myAdapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>{
private ArrayList<String> mSorten;
private Context mContext;
private Listener listener;
public interface Listener{
void click(String name);
}
//Constructor
public ListAdapter(Context mContext, ArrayList<String> sortenListe, Listener listener) {
this.mContext = mContext;
this.mSorten = sortenListe;
this.listener=listener;
}
///////////////////////
public class ViewHolder extends RecyclerView.ViewHolder {
TextView sortenName;
LinearLayout sorteLayout;
public ViewHolder(View itemView) {
super(itemView);
sortenName = itemView.findViewById(R.id.nameSorte);
sorteLayout = itemView.findViewById(R.id.sorteLayout);
}
}
////////////////////////////////
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
holder.sortenName.setText(mSorten.get(position));
holder.sorteLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.click(mSorten.get(position));
}
});
}
@Override
public int getItemCount() {
return mSorten.size();
}
}
arr[0] = "Hi " + name + ", Welcome"
arr[1] = "Happy Birthday " + name;
arr[2] = "You are " + name;
答案 0 :(得分:0)
在Android中,只有UI线程可以更新视图。 (由于onPostExecute
正在切换到UI线程,因此可以在onPostExecute
中触发UI更新。)
由于您仍处于doInBackground()
函数中,因此需要一个处理程序以将带有代码的Runnable发送到UI线程的MessageQueue。
因此,在您的DataContainer中,将onProgressUpdate
更改为
protected void onProgressUpdate(Void... values) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run() {
myAdapter.notifyDataSetChanged();
}
});
super.onProgressUpdate(values);
}