具有多个ViewTypes的Android Recyclerview无法正常工作

时间:2017-09-19 00:33:35

标签: android android-recyclerview android-viewholder

我创建了一个包含两种不同视图类型的Recyclerview。一个用于列表为空时,一个用于列表中有数据时。从我在日志中看到的,唯一被调用的方法是getItemCount()。我无法弄清楚为什么这是被调用的唯一方法或我做错了什么。以下是我的代码。

empty_view.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/emptyElement"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="No Goals Added"
    android:textColor="#525252"
    android:textSize="19sp" />

content_goals.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/goals_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"
    android:divider="@android:color/darker_gray"
    android:dividerHeight="1px"
    />

GoalsActivity.java

GoalsRecyclerViewAdapter adapter;
RecyclerView goalsListView;
....

goalsListView = (RecyclerView) findViewById(R.id.goals_list);

....

 private void createGoalsList() {
    //set array adapter for the goals list
    adapter = new GoalsRecyclerViewAdapter(new ArrayList<Goal>());
    goalsListView.setAdapter(adapter);
}

GoalsRecyclerViewAdapter.java

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

private static final String TAG = GoalsRecyclerViewAdapter.class.getSimpleName();

List<Goal> mGoals;
private final int EMPTY=0, GOAL=1;

public GoalsRecyclerViewAdapter(List<Goal> goals) {
    Log.d(TAG, "adapter initialized");
    mGoals = goals;
}

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

    Log.d(TAG, "onCreateViewHolder: inside");
    RecyclerView.ViewHolder viewHolder;
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View emptyView = inflater.inflate(R.layout.empty_view, parent, false);

    Log.d(TAG, "onCreateViewHolder: viewType" + viewType);

    switch (viewType){
        case EMPTY:
            viewHolder = new EmptyViewHolder(emptyView);
        break;
        case GOAL:
            View goalsView = inflater.inflate(R.layout.goal_row, parent, false);
            viewHolder = new GoalsViewHolder(goalsView);
            break;
        default:
            viewHolder = new EmptyViewHolder(emptyView);
            break;
    }

    return viewHolder;

}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    Log.d(TAG, "onBindViewHolder: inside");
    EmptyViewHolder emptyViewHolder= (EmptyViewHolder) holder;

    switch (holder.getItemViewType()){
        case GOAL:
            GoalsViewHolder goalsViewHolder = (GoalsViewHolder) holder;
            goalsViewHolder.bind(goalsViewHolder, position);
            break;
        case EMPTY:
            emptyViewHolder.bind(emptyViewHolder, position);
            break;
        default:
            emptyViewHolder.bind(emptyViewHolder, position);
            break;
    }
}

@Override
public int getItemViewType(int position) {

    Log.d(TAG, "getItemViewType: inside");

    if(mGoals.size()== EMPTY){
        return EMPTY;
    }else{
        return GOAL;
    }
}

@Override
public int getItemCount() {
    Log.d(TAG, "getItemCount: " + mGoals.size());
    return mGoals.size();
}

public class GoalsViewHolder extends RecyclerView.ViewHolder {

    TextView goalsLabel, goalCount;
    public GoalsViewHolder(View itemView) {
        super(itemView);
        goalsLabel = (TextView) itemView.findViewById(R.id.calls_goal_label);
        goalCount = (TextView) itemView.findViewById(R.id.goal_count);
    }

    public void bind(GoalsViewHolder vh, int position){
        Goal goal = mGoals.get(position);
        vh.goalsLabel.setText(goal.getGoalTitle());
        vh.goalCount.setText(goal.getGoalFrequency());
    }
}

public class EmptyViewHolder extends RecyclerView.ViewHolder{

    TextView emptyTextView;
    public EmptyViewHolder(View itemView) {
        super(itemView);
        emptyTextView = (TextView) itemView.findViewById(R.id.emptyElement);
    }

    public void bind(EmptyViewHolder vh, int position){

        vh.emptyTextView.setText("No Goals Added");
    }
}

日志

09-18 20:09:09.990 26382-26382/com.ubcma.leadster D/GoalsRecyclerViewAdapter: adapter initialized
09-18 20:09:10.020 896-947/? D/StatusBarManagerService: disable:userId=0 what=0x0 which=0x1 pkg=Window{8a95441 u0 com.ubcma.leadster/com.ubcma.leadster.activity.GoalsActivity}
09-18 20:09:10.040 26382-26382/com.ubcma.leadster D/GoalsRecyclerViewAdapter: getItemCount: 0
09-18 20:09:10.050 26382-26382/com.ubcma.leadster D/GoalsRecyclerViewAdapter: getItemCount: 0
09-18 20:09:10.090 896-1002/? I/ActivityManager: Displayed com.ubcma.leadster/.activity.GoalsActivity: +202ms
09-18 20:09:10.100 26382-26382/com.ubcma.leadster D/GoalsRecyclerViewAdapter: getItemCount: 0
09-18 20:09:10.100 26382-26382/com.ubcma.leadster D/GoalsRecyclerViewAdapter: getItemCount: 

2 个答案:

答案 0 :(得分:0)

无需使用两个xml布局。让它与可见性一起使用。我在下面的示例中使用了它。它肯定会奏效。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:clickable="true"
    android:orientation="vertical">
<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/goals_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"
    android:divider="@android:color/darker_gray"
    android:dividerHeight="1px"
    android:visibility="gone"
    />

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/emptyElement"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="No Goals Added"
    android:textColor="#525252"
    android:textSize="19sp"
    android:visibility="gone" />
</LinearLayout>

然后如下所示更改您的GoalsActivity.java

GoalsRecyclerViewAdapter adapter;
RecyclerView goalsListView;
TextView noGoalsTxt;
....

goalsListView = (RecyclerView) findViewById(R.id.goals_list);
noGoalsTxt = (TextView) findViewById(R.id.emptyElement);
....

 private void createGoalsList() {
    //check your goals list is empty or not
     if(Goal!=null && Goal.size()>0{
    //set array adapter for the goals list
   goalsListView.setVisibility(View.VISIBLE);
    noGoalsTxt..setVisibility(View.GONE);
    adapter = new GoalsRecyclerViewAdapter(new ArrayList<Goal>());
    goalsListView.setAdapter(adapter);
   }else{
           goalsListView.setVisibility(View.GONE);
    noGoalsTxt..setVisibility(View.VISIBLE);
   }

}

答案 1 :(得分:0)

我刚才试过。问题出在Method getItemCount .if list.size == 0,然后会返回0,所以不会显示