Android RecyclerView无法正确显示元素

时间:2015-12-05 15:31:00

标签: android android-recyclerview

当我运行应用程序而不是显示RecyclerView列表时,它显示空白页面,并在控制台中显示错误:D/OpenGLRenderer: endAllStagingAnimators on 0x6dd9c400 (CardView) with handle。 SB可以帮助我吗?这是我的细节问题:

我在RecyclerView中显示项目时遇到了非常奇怪的问题。首先它不显示项目(奇怪的D/OpenGLRenderer: endAllStagingAnimators on 0x6dd9c400 (CardView) with handle 0x6861d090出现 - 从未发生过)并且后退按钮不起作用(它出现但没有反应)。好吧让我们开始。我有一些Fragment(这是带有RecyclerView的片段:

enter image description here

我也有1个相同的片段,但其中一个片段可以看到kitchen types,第二个片段有meal types。当我点击其中一个列表项时,在两种情况下,操作都会将我重定向到新活动

当我点击其中的一些项目时,首先是这个RecyclerView适配器内发生的事情:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    KitchenTypeItem kitchenItem = kitchenItems.get(position);
    holder.kitchenTypeName.setText("Kuchnia " + kitchenItem.getKitchenName());
    holder.kitchenTypeImgThumbnail.setImageResource(kitchenItem.getKitchenThumbnail());
    holder.kitchenTypeDescription.setText(kitchenItem.getKitchenDescription());

    holder.setClickListener(new ItemClickListener() {

        @Override
        public void onClick(View view, int position) {
            KitchenTypeItem kitchenItem = kitchenItems.get(position);

            Intent intent = new Intent(context, RecipeActivity.class);
            intent.putExtra(TYPE_NAME, kitchenItem.getKitchenName());
            intent.putExtra(DISPLAY_TYPE, 0);
            context.startActivity(intent);
        }

    });
}

当我按下其中一个项目时,我将2个参数发送到新活动:TYPE_NAME - 帮助我了解是否将使用新打开的活动从包含kitchen types的服务器下载数据食谱或meal types食谱和DISPLAY_TYPE - 用于向MySQL数据库发送请求。这是来自第二个适配器的一些代码(因为你几乎可以相同):

        Intent intent = new Intent(context, RecipeActivity.class);
        intent.putExtra(TYPE_NAME, mealItem.getMealName());
        intent.putExtra(DISPLAY_TYPE, 1);
        context.startActivity(intent);

这是我在新开展的活动中获得的内容:

enter image description here

正如你所看到的那样,尽管事实上RecipeAdapter正确,但我认为没有任何事情在发生:

在这里你有代码:

public class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.ViewHolder> {

    private static String TAG = RecipeAdapter.class.getSimpleName().toString();

    private Context context;
    private ArrayList<RecipeItem> recipeItems;
    private CoordinatorLayout coordinatorLayout;

    public RecipeAdapter(Context context, ArrayList<RecipeItem> recipeItems) {
        this.context = context;
        this.recipeItems = recipeItems;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item, parent,
                false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        RecipeItem recipeItem = recipeItems.get(position);
        Picasso.with(context).load(recipeItem.getRecipeImgThumbnailLink()).into(
                holder.recipeItemImgThumbnail);
        holder.recipeItemTitle.setText(recipeItem.getRecipeTitle());
        holder.recipeItemKitchenMealType.setText("Kuchnia " + recipeItem.getRecipeKitchenType() +
                ", " + recipeItem.getRecipeMealType());
        holder.recipeItemAddDate.setText(recipeItem.getRecipeAddDate());
        holder.recipeItemLikeCount.setText(recipeItem.getRecipeLikeCount());
        holder.setClickListener(new ItemClickListener2() {

            @Override
            public void onClick(View view, int position, boolean isLongClick) {
                if (!isLongClick) {
                    // go to recipes site
                } else {
                    RecipeItem recipeItem = recipeItems.get(position);
                    FragmentActivity fragmentActivity = (FragmentActivity)(context);
                    FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
                    RecipeAddDialogFragment recipeDialogFragment = new RecipeAddDialogFragment();
                    Log.d(TAG, "Ustawiono recipeUniqueId, coordinatorLayout oraz " +
                            "recipeDialogFragment w klasie RecipeAddDialogFragment");
                    recipeDialogFragment.setReferences(recipeItem.getRecipeUniqueID(),
                            coordinatorLayout, recipeDialogFragment);

                    Log.d(TAG, "Uruchamiam okno dialogowe RecipeAddDialogFragment");
                    recipeDialogFragment.show(fragmentManager, "recipeDialogFragment");
                }
            }

        });
    }

    @Override
    public int getItemCount() {
        return recipeItems.size();
    }

    // Recipe Item Holder
    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
            View.OnLongClickListener {

        private ImageView recipeItemImgThumbnail;
        private TextView recipeItemTitle;
        private TextView recipeItemKitchenMealType;
        private TextView recipeItemAddDate;
        private TextView recipeItemLikeCount;
        private ItemClickListener2 clickListener2;

        public ViewHolder(View itemView) {
            super(itemView);
            recipeItemImgThumbnail = (ImageView) itemView.findViewById(
                    R.id.recipe_item_img_thumbnail);
            recipeItemTitle = (TextView) itemView.findViewById(R.id.recipe_item_title);
            recipeItemKitchenMealType = (TextView) itemView.findViewById(
                    R.id.recipe_item_kitchen_meal_type);
            recipeItemAddDate = (TextView) itemView.findViewById(R.id.recipe_item_add_date);
            recipeItemLikeCount = (TextView) itemView.findViewById(R.id.recipe_item_like_count);

            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);
        }

        public void setClickListener(ItemClickListener2 itemClickListener2) {
            this.clickListener2 = itemClickListener2;
        }

        @Override
        public void onClick(View view) {
            clickListener2.onClick(view, getAdapterPosition(), false);
        }

        @Override
        public boolean onLongClick(View view) {
            clickListener2.onClick(view, getAdapterPosition(), true);

            return true;
        }
    }

    public void setCoordinatorLayout(CoordinatorLayout coordinatorLayout) {
        this.coordinatorLayout = coordinatorLayout;
    }
}

以下是该活动的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/recipe_activity_coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".RecipeActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/log_reg_background"
        android:orientation="vertical">

        <!-- Toolbar -->
        <include
            android:id="@+id/toolbar"
            layout="@layout/tool_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/activity_recipe_recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="8dp"
            android:clipToPadding="false"/>

    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

这是活动的主要代码:

public class RecipeActivity extends AppCompatActivity {

    private static String TAG = RecipeActivity.class.getSimpleName().toString();

    private ArrayList<RecipeItem> recipeItems;
    private RecipeAdapter recipeAdapter;
    private ProgressDialog pDialog;
    private CoordinatorLayout coordinatorLayout;
    private BroadcastReceiver broadcastReceiver;
    private int offset;

    private String typeName;
    private int displayType;

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        offset = 0;

        recipeItems = new ArrayList<>();

        coordinatorLayout = (CoordinatorLayout) findViewById(
                R.id.recipe_activity_coordinator_layout);

        RecyclerView recipeRecyclerView  = (RecyclerView) findViewById(
                R.id.activity_recipe_recyclerview);

        recipeAdapter = new RecipeAdapter(getApplicationContext(), recipeItems);

        recipeAdapter.setCoordinatorLayout(coordinatorLayout);

        recipeRecyclerView.setHasFixedSize(true);
        recipeRecyclerView.setAdapter(recipeAdapter);
        recipeRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
        recipeRecyclerView.setItemAnimator(new DefaultItemAnimator());

        getBundleExtras();  // Getting Argument Passed By Meal Or Kitchen Type Adapter
        setActivityTitle(); // Setting Title Depending On Adapter Type

        setBroadcastReceiver();
    }

    @Override
    public void onResume() {
        registerReceiver(broadcastReceiver, new IntentFilter(
                "android.net.conn.CONNECTIVITY_CHANGE"));
        Log.d(TAG, "Zarejestrowano BroadcastReceiver'a");
        super.onResume();
    }

    @Override
    public void onPause() {
        unregisterReceiver(broadcastReceiver);
        Log.d(TAG, "Wyrejestrowano BradcasReceiver'a");
        super.onPause();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.home) {
            NavUtils.navigateUpFromSameTask(this);

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void getBundleExtras() {
        Bundle extras = getIntent().getExtras();
        // Static Fields Could Bo From MealAdapter Aswell
        typeName = extras.getString(KitchenTypeAdapter.TYPE_NAME);
        displayType = extras.getInt(KitchenTypeAdapter.DISPLAY_TYPE);
        Log.d(TAG, "Trzymano dane z listy fragmentu: typeName=" + typeName + ", displayType=" +
                displayType);
    }

    private void setActivityTitle() {
        switch (displayType) {
            case 0: {
                setTitle(getString(R.string.nav_kitchen_type));
                Log.d(TAG, "Ustawiono tytuł: " + displayType);
                break;
            }
            case 1: {
                setTitle(getString(R.string.nav_meal_type));
                Log.d(TAG, "Ustawiono tytuł: " + displayType);
                break;
            }
        }
    }

    private void setBroadcastReceiver() {
        broadcastReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
                        Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                if (activeNetwork == null) {
                    Log.d(TAG, "Brak połączenia. Pokazuję komuikat.");
                    showSnackbarInfo(getString(R.string.err_msg_connection_problem),
                            R.color.snackbar_error_msg);
                } else {
                    if (recipeItems.isEmpty()) {
                        Log.d(TAG, "Jest połączenie. Listy puste. Pobieram przepisy.");
                        getRecipes();
                    } else {
                        Log.d(TAG, "Jest połączenie. Listy pełne. Nic nie robię.");
                    }
                }
            }

        };
    }

    private void getRecipes() {
        switch (displayType) {
            case 0: {
                Log.d(TAG, "Pobieranie przepisów z warunkiem typ_kuchnii");
                getKitchenTypeRecipes();
                break;
            }
            case 1: {
                Log.d(TAG, "Pobieranie przepisów z warunkiem typ_posiłku");
                getMealTypeRecipes();
                break;
            }
        }
    }

    private void getKitchenTypeRecipes() {
        JsonArrayRequest kitchenTypeRecipesReq = new JsonArrayRequest(prepareGetMethodUrl(),
                new Response.Listener<JSONArray>() {

                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d("odpowiedz", "Odpowiedź przepisów: " + response.toString());
                        Log.d("odpowiedz", "Dlugosc response: " + Integer.toString(
                                response.length()));
                        if (response.length() == 0) {
                            showSnackbarInfo("Na serwerze nic nie ma (kitchen type)", R.color.snackbar_info_msg);
                        } else {
                            for (int i = 0; i < response.length(); i++) {
                                try {
                                    JSONObject jObj = response.getJSONObject(i);
                                    RecipeItem recipeItem = new RecipeItem();
                                    recipeItem.setRecipeUniqueID(jObj.getString("unique_id"));
                                    recipeItem.setRecipeTitle(jObj.getString("title"));
                                    recipeItem.setRecipeImgThumbnailLink(jObj.getString(
                                            "img_tumbnail_link"));
                                    recipeItem.setRecipeAddAte(jObj.getString("add_date"));
                                    recipeItem.setRecipeKitchenType(jObj.getString("kitchen_type"));
                                    recipeItem.setRecipeMealType(jObj.getString("meal_type"));
                                    recipeItem.setRecipeLikeCount(jObj.getString("like_count"));

                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                            recipeAdapter.notifyItemRangeInserted(recipeItems.size(),
                                    response.length());
                        }
                    }

                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e("odpowiedz", "Błąd pobierania przepisów (kichen type): " +
                                Integer.toString(error.networkResponse.statusCode));

                        showSnackbarInfo(Integer.toString(error.networkResponse.statusCode),
                                R.color.snackbar_error_msg);
                    }

                });
        AppController.getInstance().addToRequestQueue(kitchenTypeRecipesReq);
    }

    private void getMealTypeRecipes() {
        JsonArrayRequest mealTypeRecipesReq = new JsonArrayRequest(prepareGetMethodUrl(),
                new Response.Listener<JSONArray>() {

                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d("odpowiedz", "Odpowiedź przepisów: " + response.toString());
                        Log.d("odpowiedz", "Dlugosc response: " + Integer.toString(
                                response.length()));
                        if (response.length() == 0) {
                            showSnackbarInfo("Na serwerze nic nie ma (meal_type)",
                                    R.color.snackbar_info_msg);
                        } else {
                            for (int i = 0; i < response.length(); i++) {
                                try {
                                    JSONObject jObj = response.getJSONObject(i);
                                    RecipeItem recipeItem = new RecipeItem();
                                    recipeItem.setRecipeUniqueID(jObj.getString("unique_id"));
                                    recipeItem.setRecipeTitle(jObj.getString("title"));
                                    recipeItem.setRecipeImgThumbnailLink(jObj.getString(
                                            "img_tumbnail_link"));
                                    recipeItem.setRecipeAddAte(jObj.getString("add_date"));
                                    recipeItem.setRecipeKitchenType(jObj.getString("kitchen_type"));
                                    recipeItem.setRecipeMealType(jObj.getString("meal_type"));
                                    recipeItem.setRecipeLikeCount(jObj.getString("like_count"));

                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                            recipeAdapter.notifyItemRangeInserted(recipeItems.size(),
                                    response.length());
                        }
                    }

                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                            Log.e("odpowiedz", "Błąd pobierania przepisów (meal type): " +
                                    Integer.toString(error.networkResponse.statusCode));

                        showSnackbarInfo(Integer.toString(error.networkResponse.statusCode),
                                R.color.snackbar_error_msg);
                    }

                });
        AppController.getInstance().addToRequestQueue(mealTypeRecipesReq);
    }

    private String prepareGetMethodUrl() {
        switch (displayType) {
            case 0: {
                return AppConfig.URL_GETRECIPESBYKITCHENTYPE + "?kitchen_type=" + typeName +
                        "&offset=" + Integer.toString(offset);
            }

            case 1: {
                return AppConfig.URL_GETRECIPESBYMEALTYPE + "?meal_type=" + typeName +
                        "&offset=" + Integer.toString(offset);
            }

            default:
                return null;
        }
    }

    // Showing Dialog Window
    private void showDialog() {
        if (!pDialog.isShowing()) {
            pDialog.show();
        }
    }

    // Hiding Dialog Window
    private void hideDialog() {
        if (pDialog.isShowing()) {
            pDialog.dismiss();
        }
    }

    // Fucntion Showing Text In Snackbar
    private void showSnackbarInfo(String info, int textColor) {
        Snackbar snackbar = Snackbar.make(coordinatorLayout, info, Snackbar.LENGTH_LONG);

        View sbView = snackbar.getView();
        TextView sbText = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
        sbText.setTextColor(ContextCompat.getColor(getApplicationContext(), textColor));

        snackbar.show();
    }
}

我可以保证下载时一切正常,putExtra工作正常,这样参数就可以正确发送。只是显示它的问题和那个奇怪的错误:D/OpenGLRenderer: endAllStagingAnimators on 0x6dd9c400 (CardView) with handle 0x6861d090而不是up button。某事可以帮助我吗?

修改

这个问题已经解决了一半。我没有注意到在下载数据后我没有将其插入ArrayList。现在只有Back Navigation Button无效。任何想法为什么它没有反应?

1 个答案:

答案 0 :(得分:0)

对于您的后退导航按钮,您已完成此操作:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.home) {
        NavUtils.navigateUpFromSameTask(this);

        return true;
    }

    return super.onOptionsItemSelected(item);
}

相反,它应该是这样的:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
        switch (id) {
        case android.R.id.home:
            onBackPressed();
            break;
        }
    return super.onOptionsItemSelected(item);
}