繁体   English   中英

数据更新后 RecyclerView 为空

[英]RecyclerView empty after data update

我正在开发 Android 应用程序,它从服务器获取有关餐馆的信息并在 RecyclerView 中显示它们。 当从服务器获取第一个 package 信息时,一切正常,但是,当我更改搜索条件并从服务器请求新的 package 信息时,RecyclerView 变为空白。 我使用 Toasts 来调试来自服务器的内容,并且我确信数据的格式正确。 此外,根据我的观察,用于接受数据的变量也在代码中得到了适当的处理。 你可能知道为什么我的 RecyclerView 在显示第二个 package 数据时是空的吗? 这是代码。

AfterLoginActivity.java

public class AfterLoginActivity extends AppCompatActivity {

/* interface main elements */
LinearLayout afterLoginLayout;
LinearLayout restaurantListLayout;
EditText restaurantEditText;
Button findRestaurantButton;
LoadingDialog loadingDialog;
AlphaAnimation loadingAnimation;
RecyclerView restaurantsRecyclerView;
int recycler_set = 0;
Button signOutButton;
GoogleSignInClient mGoogleSignInClient;
MyAdapter myAdapter = null;

/* server-client communication data */
public static String UploadUrl = "https://gdedakliknem.com/klopator.php";
public static String[] received;
String restaurants[] = new String[40];
String logos_as_strings[] = new String[40];
Bitmap logos[] = new Bitmap[40];
int num_of_elements = 0;
int data_received = 0;

/* user data */
String person_email;
String person_name;
String restaurant;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_after_login);

    /* interface main elements */
    afterLoginLayout = findViewById(R.id.afterLoginLayout);
    restaurantListLayout = findViewById(R.id.restaurantListLayout);
    restaurantEditText = findViewById(R.id.restaurantEditText);
    findRestaurantButton = findViewById(R.id.findRestaurantButton);
    restaurantsRecyclerView = findViewById(R.id.restaurantsRecyclerView);
    signOutButton = findViewById(R.id.signOutButton);
    loadingAnimation = new AlphaAnimation(1F, 0.8F);
    loadingDialog = new LoadingDialog(AfterLoginActivity.this);

    /* UPDATING INTERFACE ELEMENTS */

    /* execution thread */
    final Handler handler = new Handler();
    final int delay = 2000; // 1000 milliseconds == 1 second

    handler.postDelayed(new Runnable() {
        public void run() {

            /* check if recycler view is set */
            if(recycler_set == 0){
                /* if not, check if there is data to fil it with */
                if(data_received == 1){
                    /* convert received strings to images */
                    for(int i = 0; i < num_of_elements; i++){
                        logos[i] = stringToBitmap(logos_as_strings[i]);
                    }

                    /* fill interface elements */
                    loadingDialog.dismissDialog();
                    myAdapter = new MyAdapter(AfterLoginActivity.this, restaurants, logos, num_of_elements);
                    restaurantsRecyclerView.setAdapter(myAdapter);
                    restaurantsRecyclerView.setLayoutManager(new LinearLayoutManager(AfterLoginActivity.this));
                    afterLoginLayout.setVisibility(View.GONE);
                    restaurantListLayout.setVisibility(View.VISIBLE);
                    recycler_set = 1;
                }
            }
            handler.postDelayed(this, delay);
        }
    }, delay);

    /* catch restaurant name from user's entry */
    findRestaurantButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            restaurant = restaurantEditText.getText().toString();
            if(!restaurant.isEmpty()){
                view.startAnimation(loadingAnimation);
                loadingDialog.startLoadingDialog();
                sendRequest();
            } else{
                Toast.makeText(AfterLoginActivity.this, "Unesite naziv restorana!", Toast.LENGTH_LONG).show();
            }
        }
    });

    /* enable signing out */
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();
    mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
    signOutButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.signOutButton:
                    signOut();
                    break;
            }
        }
    });

    /* obtaining email */
    GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(this);
    if (acct != null) {
        person_email = acct.getEmail();
        person_name = acct.getDisplayName();
    }
}

@Override
public void onBackPressed() {
    afterLoginLayout.setVisibility(View.VISIBLE);
    restaurantsRecyclerView.setVisibility(View.GONE);
    data_received = 0;
    recycler_set = 0;
}

private void signOut() {
    mGoogleSignInClient.signOut()
            .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    Toast.makeText(AfterLoginActivity.this, "Signed out", Toast.LENGTH_LONG).show();
                    finish();
                }
            });
}

public void sendRequest(){

    StringRequest stringRequest = new StringRequest(Request.Method.POST, UploadUrl, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            try {
                JSONObject jsonObject = new JSONObject(response);
                String Response = jsonObject.getString("response");
                if (Response.equals("Restaurant not found")){
                    loadingDialog.dismissDialog();
                    Toast.makeText(getApplicationContext(), "Uneti restoran ne postoji u sistemu! Proverite da li ste dobro napisali naziv", Toast.LENGTH_LONG).show();
                } else{
                    received = Response.split(";");
                    if (received.length > 0){
                        data_received = 1;
                        num_of_elements = received.length / 2;
                        //Toast.makeText(getApplicationContext(), "num of elements: " + num_of_elements, Toast.LENGTH_LONG).show();
                        for(int i = 0; i < num_of_elements; i++){
                            logos_as_strings[i] = received[i*2];
                            restaurants[i] = received[i*2+1];
                            //Toast.makeText(getApplicationContext(), "restaurants: " + restaurants, Toast.LENGTH_LONG).show();
                        }
                    } else{
                        loadingDialog.dismissDialog();
                        Toast.makeText(getApplicationContext(), "Greška u prijemu", Toast.LENGTH_LONG).show();
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(final VolleyError error) {
            //volleyError = error;
        }
    })

    {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {

            //Toast.makeText(getApplicationContext(), "get params", Toast.LENGTH_LONG).show();

            Map<String, String> params = new HashMap<>();
            params.put("control", "find_restaurant");
            params.put("restaurant", restaurant);

            return params;
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(AfterLoginActivity.this);
    requestQueue.add(stringRequest);
}

public static Bitmap stringToBitmap(String encodedString) {
    try {
        byte[] encodeByte = Base64.decode(encodedString, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);

    } catch (Exception e) {
        e.getMessage();
        return null;
    }
}

MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

String restaurants[];
Bitmap logos[];
Context context;
int num_of_elements;

public MyAdapter(Context ct, String rests[], Bitmap lgs[], int num){
    context = ct;
    restaurants = rests;
    logos = lgs;
    num_of_elements = num;

    Toast.makeText(context, Integer.toString(restaurants.length), Toast.LENGTH_LONG).show();

    for(int i = 0; i < restaurants.length; i++){
        Toast.makeText(context, restaurants[i], Toast.LENGTH_SHORT).show();
    }
}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater layoutInflater = LayoutInflater.from(context);
    View view = layoutInflater.inflate(R.layout.restaurant_item_layout, parent, false);
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position) {
    holder.restaurantNameTextView.setText(restaurants[position]);
    holder.restaurantLogoImageView.setImageBitmap(logos[position]);
    holder.restaurantItemLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(context, AfterPickingRestaurantActivity.class);
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            logos[position].compress(Bitmap.CompressFormat.PNG, 50, bs);
            intent.putExtra("byteArray", bs.toByteArray());
            intent.putExtra("picked_restaurant_name", restaurants[position]);
            context.startActivity(intent);
        }
    });
}

@Override
public int getItemCount() {
    /*
    int i = 0;
    if (restaurants != null){
        while(restaurants[i] != null){
            i++;
        }
    } else{
        i = restaurants.length;
    }

    return i;
    */
    return num_of_elements;
}

public class MyViewHolder extends RecyclerView.ViewHolder {

    TextView restaurantNameTextView;
    ImageView restaurantLogoImageView;
    LinearLayout restaurantItemLayout;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        restaurantNameTextView = itemView.findViewById(R.id.restaurantNameTextView);
        restaurantLogoImageView = itemView.findViewById(R.id.restaurantLogoImageView);
        restaurantItemLayout = itemView.findViewById(R.id.restaurantItemLayout);
    }
}

获取新数据后添加此行

myAdapter.notifyDataSetChanged()

您的适配器已经在 OnCreate 方法中设置了 RecyclerView。

因此,当您单击findRestaurantButton时,您只会从服务器获取 Resturent 数据,但收集的数据不会传入适配器,这就是为什么要获取空白适配器的原因。

只需在数组中设置数据后将此行放在您的onResponse中。

myAdapter.notifyDataSetChanged()

我发现错误在哪里。 如果您查看覆盖后退按钮单击的部分,我错误地设置为 GONE recyclerView 本身:

restaurantsRecyclerView.setVisibility(View.GONE);

而不是包含 recyclerView 的 LinearLayout。 期望的行动是:

restaurantListLayout.setVisibility(View.GONE);

PS 一切都可以在不调用 notifyDataSetChanged() 的情况下工作,我每次收到新数据时都会创建一个新的 myAdapater 实例。 我希望垃圾收集器能完成它的工作:)

谢谢大家帮忙!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM