onCreateView 等待查询结果
onCreateView wait queries result
我需要对我的数据库执行查询以获取一些 ID,然后使用这些 ID 对 Realm DB 执行另一个查询,然后 return 将结果发送给用于创建 UI.我的问题是适配器是在 onCreatView(主线程)中创建的,我需要等待查询结果。你知道我该怎么做吗?非常感谢:)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Realm realm = Realm.getDefaultInstance();
cardList = new ArrayList(realm.where(Card.class).findAll().sort("rarity"));
View rootView = inflater.inflate(R.layout.inventory_fragment_layout, null);
RecyclerView recyclerView = rootView.findViewById(R.id.inventory_recycler);
recyclerView.setLayoutManager(new GridLayoutManager(this.getContext(), 2));
adapter = new inventoryFragmentRecyclerAdapter(this.getContext(), getCards()); <----- getCards() is used here.
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
TextView topText = rootView.findViewById(R.id.inv_topText);
topText.setTypeface(Typeface.createFromAsset(getActivity().getAssets(), "fonts/Square.ttf"));
return rootView;
}
.
.
.
.
.
.
public List<Card> getCards() { //It is used when adapter is created, and it need to contain all cards to display
//Realm realm = Realm.getDefaultInstance();
String urlToGet = "myurl";
String user_name = settings.getString("username", null);
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.add("user_name", user_name)
.build();
Request request = new Request.Builder()
.url(urlToGet)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
responseCardInInventory = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
List<CardInInv> cardListInInv = new ArrayList<>();
Gson gson = new Gson();
CardInInventory civ = gson.fromJson(responseCardInInventory, CardInInventory.class);
cardListInInv = getCards(civ);
//HERE I NEED TO USE REALM TO EXECUTE A QUERY USING cardListInInv
}
});
}
});
//HERE I NEED TO RETURN THE RESULT OF THE QUERY EXECUTED BEFORE
return cardsIninv;
}
编辑 1:这是我的适配器代码
public class inventoryFragmentRecyclerAdapter extends RecyclerView.Adapter<inventoryFragmentRecyclerAdapter.ViewHolder> {
private List<Card> dataCard = new ArrayList<>();
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public inventoryFragmentRecyclerAdapter(Context context, List<Card> data) {
this.mInflater = LayoutInflater.from(context);
this.dataCard = data;
}
// inflates the cell layout from xml when needed
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.inventory_rw, parent, false);
return new ViewHolder(view);
}
// binds the data to the in each cell
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.cardImage.setImageBitmap(BitmapFactory.decodeByteArray(dataCard.get(position).getCardImage(), 0, dataCard.get(position).getCardImage().length));
}
// total number of cells
@Override
public int getItemCount() {
return dataCard.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView cardImage;
//instanzio le componenti della pagina
ViewHolder(View itemView) {
super(itemView);
cardImage = itemView.findViewById(R.id.inv_rw_cardimage);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
Card getItem(int id) {
return dataCard.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
将您的查询移至您的适配器并使用空列表启动您的适配器。在构造函数的末尾进行查询调用。成功完成查询后,通知适配器它已更改,并让它在查询成功结束时使用新数据处理更改。所以在这样做之后你的适配器看起来像这样。
public inventoryFragmentRecyclerAdapter(Context context, List<Card> data) {
this.mInflater = LayoutInflater.from(context);
getCards();
}
public void getCards() { //It is used when adapter is created, and it need to contain all cards to display
//Realm realm = Realm.getDefaultInstance();
String urlToGet = "myurl";
String user_name = settings.getString("username", null);
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.add("user_name", user_name)
.build();
Request request = new Request.Builder()
.url(urlToGet)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
responseCardInInventory = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
List<CardInInv> cardListInInv = new ArrayList<>();
Gson gson = new Gson();
CardInInventory civ = gson.fromJson(responseCardInInventory, CardInInventory.class);
cardListInInv = getCards(civ);
//use realm to do all your card inventory stuff to get your resulting object
dataCard = yourObjectListAfterUsingRealm;
notifyDataSetChanged();
}
});
}
});
}
移动这条行 adapter = new inventoryFragmentRecyclerAdapter(context, yourList);
在 onResponse()
内并直接传递列表而不使用 getCards();
编辑:
当您的数据为 ready.where 时初始化您的适配器?这取决于您的需求。
或用空列表初始化它并在发生变化时调用adapter.notifyDataSetChanged()
(从列表中添加或删除或初始化一个全新的列表)
使用空列表创建适配器
adapter = new inventoryFragmentRecyclerAdapter(this.getContext(), new ArrayList<Card>());
然后在你的适配器中创建一个这样的方法
public void updateCardList(List<Card> cardList) {
this.mCards = cardList;
notifyDataSetChanged();
}
并在
中调用此函数
@Override
public void onResponse(Call call, final Response response)
我需要对我的数据库执行查询以获取一些 ID,然后使用这些 ID 对 Realm DB 执行另一个查询,然后 return 将结果发送给用于创建 UI.我的问题是适配器是在 onCreatView(主线程)中创建的,我需要等待查询结果。你知道我该怎么做吗?非常感谢:)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Realm realm = Realm.getDefaultInstance();
cardList = new ArrayList(realm.where(Card.class).findAll().sort("rarity"));
View rootView = inflater.inflate(R.layout.inventory_fragment_layout, null);
RecyclerView recyclerView = rootView.findViewById(R.id.inventory_recycler);
recyclerView.setLayoutManager(new GridLayoutManager(this.getContext(), 2));
adapter = new inventoryFragmentRecyclerAdapter(this.getContext(), getCards()); <----- getCards() is used here.
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
TextView topText = rootView.findViewById(R.id.inv_topText);
topText.setTypeface(Typeface.createFromAsset(getActivity().getAssets(), "fonts/Square.ttf"));
return rootView;
}
.
.
.
.
.
.
public List<Card> getCards() { //It is used when adapter is created, and it need to contain all cards to display
//Realm realm = Realm.getDefaultInstance();
String urlToGet = "myurl";
String user_name = settings.getString("username", null);
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.add("user_name", user_name)
.build();
Request request = new Request.Builder()
.url(urlToGet)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
responseCardInInventory = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
List<CardInInv> cardListInInv = new ArrayList<>();
Gson gson = new Gson();
CardInInventory civ = gson.fromJson(responseCardInInventory, CardInInventory.class);
cardListInInv = getCards(civ);
//HERE I NEED TO USE REALM TO EXECUTE A QUERY USING cardListInInv
}
});
}
});
//HERE I NEED TO RETURN THE RESULT OF THE QUERY EXECUTED BEFORE
return cardsIninv;
}
编辑 1:这是我的适配器代码
public class inventoryFragmentRecyclerAdapter extends RecyclerView.Adapter<inventoryFragmentRecyclerAdapter.ViewHolder> {
private List<Card> dataCard = new ArrayList<>();
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public inventoryFragmentRecyclerAdapter(Context context, List<Card> data) {
this.mInflater = LayoutInflater.from(context);
this.dataCard = data;
}
// inflates the cell layout from xml when needed
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.inventory_rw, parent, false);
return new ViewHolder(view);
}
// binds the data to the in each cell
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.cardImage.setImageBitmap(BitmapFactory.decodeByteArray(dataCard.get(position).getCardImage(), 0, dataCard.get(position).getCardImage().length));
}
// total number of cells
@Override
public int getItemCount() {
return dataCard.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView cardImage;
//instanzio le componenti della pagina
ViewHolder(View itemView) {
super(itemView);
cardImage = itemView.findViewById(R.id.inv_rw_cardimage);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
Card getItem(int id) {
return dataCard.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
将您的查询移至您的适配器并使用空列表启动您的适配器。在构造函数的末尾进行查询调用。成功完成查询后,通知适配器它已更改,并让它在查询成功结束时使用新数据处理更改。所以在这样做之后你的适配器看起来像这样。
public inventoryFragmentRecyclerAdapter(Context context, List<Card> data) {
this.mInflater = LayoutInflater.from(context);
getCards();
}
public void getCards() { //It is used when adapter is created, and it need to contain all cards to display
//Realm realm = Realm.getDefaultInstance();
String urlToGet = "myurl";
String user_name = settings.getString("username", null);
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.add("user_name", user_name)
.build();
Request request = new Request.Builder()
.url(urlToGet)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
responseCardInInventory = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
List<CardInInv> cardListInInv = new ArrayList<>();
Gson gson = new Gson();
CardInInventory civ = gson.fromJson(responseCardInInventory, CardInInventory.class);
cardListInInv = getCards(civ);
//use realm to do all your card inventory stuff to get your resulting object
dataCard = yourObjectListAfterUsingRealm;
notifyDataSetChanged();
}
});
}
});
}
移动这条行 adapter = new inventoryFragmentRecyclerAdapter(context, yourList);
在 onResponse()
内并直接传递列表而不使用 getCards();
编辑:
当您的数据为 ready.where 时初始化您的适配器?这取决于您的需求。
或用空列表初始化它并在发生变化时调用adapter.notifyDataSetChanged()
(从列表中添加或删除或初始化一个全新的列表)
使用空列表创建适配器
adapter = new inventoryFragmentRecyclerAdapter(this.getContext(), new ArrayList<Card>());
然后在你的适配器中创建一个这样的方法
public void updateCardList(List<Card> cardList) {
this.mCards = cardList;
notifyDataSetChanged();
}
并在
中调用此函数
@Override
public void onResponse(Call call, final Response response)