无法触发recyclerview的空视图

时间:2016-06-01 16:50:24

标签: android android-recyclerview

我有一个Recyclerview,我想在它空的时候显示文字/图像,但我找不到让它工作的方法。

recyclerview xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipeRefreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/list"
        android:name="ViolationFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        app:layoutManager="LinearLayoutManager"
        tools:context=".ViolationFragment"
        tools:listitem="@layout/fragment_violation" />

    <TextView
        android:id="@+id/list_empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Empty" />
</android.support.v4.widget.SwipeRefreshLayout>

片段

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    context = getActivity();

    View view = inflater.inflate(R.layout.fragment_violation_list, container, false);
    swipeContainer = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout);
    swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            // Refresh items
            updateList();
        }
    });

    //Filters
    filterPaid = ((ViolationBrowser) context).filterPaid;
    filterUnpaid = ((ViolationBrowser) context).filterUnpaid;

    recyclerView = (RecyclerView) view.findViewById(R.id.list);
    TextView emptyView = (TextView) view.findViewById(R.id.list_empty);

    adapter = new ViolationAdapter(context, getData());
    adapter.SetOnItemClickListener(new ViolationAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(View v, int position) {
            showDetailedViolationData(position);
        }
    });

    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(context));
    if (adapter.getItemCount() >0) {
        recyclerView.setVisibility(View.GONE);
        emptyView.setVisibility(View.VISIBLE);
    } else {
        recyclerView.setVisibility(View.VISIBLE);
        emptyView.setVisibility(View.GONE);
    }
    return view;
}

适配器

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

    OnItemClickListener mItemClickListener;
    List<ViolationItem> data = Collections.emptyList();
    private LayoutInflater inflater;

    public ViolationAdapter(Context context, List<ViolationItem> data) {
        inflater = LayoutInflater.from(context);
        this.data = data;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.fragment_violation, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        ViolationItem current = data.get(position);
        holder.carName.setText(current.carName);
        holder.amount.setText(current.amount);
        holder.date.setText(current.date);

        if (current.payStatus == 2) holder.payStatus.setImageResource(R.drawable.status_paid);
        else if (current.payStatus == 1)
            holder.payStatus.setImageResource(R.drawable.status_part_paid);
        else holder.payStatus.setImageResource(R.drawable.status_not_paid);
    }

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

    public void SetOnItemClickListener(final OnItemClickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }

    public ViolationItem getItem(int position) {
        return data.get(position);
    }

    public void addData(List<ViolationItem> data) {
        for (ViolationItem itm : data) {
            this.data.add(itm);
            notifyDataSetChanged();
        }
    }

    public void clearData() {
        int size = data.size();
        data.clear();
        notifyItemRangeRemoved(0, size);
    }

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }

    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView carName, amount, date;
        ImageView payStatus, showAllDetails;

        public MyViewHolder(View itemView) {
            super(itemView);
            carName = (TextView) itemView.findViewById(R.id.itemCarName);
            amount = (TextView) itemView.findViewById(R.id.itemAmount);
            date = (TextView) itemView.findViewById(R.id.itemDate);
            payStatus = (ImageView) itemView.findViewById(R.id.payStatus);
            showAllDetails = (ImageView) itemView.findViewById(R.id.showAllDetails);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (mItemClickListener != null) mItemClickListener.onItemClick(v, getLayoutPosition());
        }
    }
}

我该怎么做才能让它发挥作用?我仍然看到一个空列表而不是文本

3 个答案:

答案 0 :(得分:1)

在您的示例中,以下条件应如下所示:

if (adapter.getItemCount() <=0) 
{
    recyclerView.setVisibility(View.GONE);
    emptyView.setVisibility(View.VISIBLE);
} 
else
{
    recyclerView.setVisibility(View.VISIBLE);
    emptyView.setVisibility(View.GONE);
}

另外,在xml布局中:

 <TextView
    android:id="@+id/list_empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Empty" />

将“list_empty”放在SwipeRefreshLayout之外。

见下面的完整示例: 如果回收者视图为空,则显示空视图。

public class MainActivity extends AppCompatActivity {

SwipeRefreshLayout mSwipeRefreshLayout;
RecyclerView recyclerView;
List<String> arrayList = null;
MyAdapter mAdapter = null;
TextView list_empty;

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


    mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
    recyclerView = (RecyclerView)findViewById(R.id.itemsRecyclerView);
    list_empty = (TextView)findViewById(R.id.list_empty);
    arrayList = new ArrayList<String>(Arrays.asList(getResources().getStringArray(R.array.mobile)));
    recyclerView.setLayoutManager(new LinearLayoutManager(this));


    mAdapter = new MyAdapter((ArrayList<String>)arrayList);

    recyclerView.setAdapter(mAdapter);       

    mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            refreshContent();
        }
    });

}

private void refreshContent(){
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {

           arrayList.clear();
            mAdapter.notifyDataSetChanged();

            if(mAdapter.getItemCount()<=0)
            {
                recyclerView.setVisibility(View.GONE);
                list_empty.setVisibility(View.VISIBLE);
            }
            else
            {
                recyclerView.setVisibility(View.VISIBLE);
                list_empty.setVisibility(View.GONE);
            }
            // Stop refresh animation
            mSwipeRefreshLayout.setRefreshing(false);
        };
    },2000);
}

class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private ArrayList<String> itemsData;

    public MyAdapter(ArrayList<String> itemsData) {
        this.itemsData = itemsData;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item, null);

        // create ViewHolder

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {

   viewHolder.txtViewTitle.setText(itemsData.get(position));


    }

    // inner class to hold a reference to each item of RecyclerView
    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView txtViewTitle;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            txtViewTitle = (TextView)
itemLayoutView.findViewById(R.id.item_title);
        }
    }


    // Return the size of your itemsData (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return itemsData.size();
    }
  }
}

activity_main.xml中:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.test.demotest.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

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

<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>

content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipeRefreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/itemsRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"

        />
</android.support.v4.widget.SwipeRefreshLayout>

    <TextView
        android:id="@+id/list_empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Empty"
        android:layout_gravity="center"
        android:visibility="gone"/>

</FrameLayout>
</RelativeLayout>

item.xml:          

<!-- title -->
<TextView
    android:id="@+id/item_title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="@android:color/darker_gray"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp"
    android:textSize="22dp" />

</RelativeLayout>

答案 1 :(得分:0)

而不是创建具有多个布局的自定义RecyclerView。一个布局将您的普通Recyclerview项目和其他布局作为带有textView的空视图。

如果您的arraylist有项目,那么显示您的通常布局,否则显示空白布局。

答案 2 :(得分:0)

我解决这个问题的一种方法是使用装饰。

public class ZeroStateDecoration extends RecyclerView.ItemDecoration {

    private final int layoutId;
    private View view;
    private boolean enabled = true;

    public ZeroStateDecoration(@LayoutRes int layoutId) {
        this.layoutId = layoutId;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (enabled && parent.getChildCount() == 0) {
            if (view == null) {
                LayoutInflater inflater = LayoutInflater.from(parent.getContext());
                view = inflater.inflate(layoutId, parent, false);
            }

            view.measure(makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY), makeMeasureSpec(parent.getHeight(), View.MeasureSpec.EXACTLY));
            view.layout(parent.getLeft(), parent.getTop(), parent.getRight(), parent.getBottom());
            view.draw(c);
        }
    }
}

要使用它,只需将其添加到具有布局ID的RecyclerView即可。

recyclerView.addItemDecoration(new ZeroStateDecoration(R.layout.zero_state);