简体   繁体   中英

RecyclerView empty after data update

I am developing Android app which obtains information about restaurants from server and shows them in RecyclerView. When first package of information is obtained from server, everything works as expected, but, when I change search criteria and request new package of information from server, RecyclerView becomes blank. I used Toasts to debug what is coming from server and I am convinced that data is properly formatted. Also, variables that are used for accepting the data are also properly handled in code, according to my observations. Do you maybe know why my RecyclerView is empty when second package of data should be shown? Here is the code.

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);
    }
}

Add this lines after getting new data

myAdapter.notifyDataSetChanged()

Your Adapter Already set with RecyclerView in OnCreate Method.

so when'er you click on findRestaurantButton you just get Resturent data from server but collected data not pass in adapter so thats why to getting blank adapter..

Just put this line in your onResponse after set data in array..

myAdapter.notifyDataSetChanged()

I found out where is the mistake. If you take a look at the section where overriding of back button click is happening, I by mistake set to GONE recyclerView itself:

restaurantsRecyclerView.setVisibility(View.GONE);

instead of LinearLayout in which recyclerView is contained. Desired action was:

restaurantListLayout.setVisibility(View.GONE);

PS Everything works without calling notifyDataSetChanged(), I just create a new instance of myAdapater each time when I receive new data. I hope Garbage Collector is doing its job:)

Thanks everyone on help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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