Search code examples
androidandroid-listviewlayout-inflaterandroid-viewbinder

What is the difference between usage of setViewBinder/setViewValue and getView/LayoutInflater?


Looks like there are two possible ways to change something in the ListView rows:

  1. using of setViewBinder/setViewValue:

    myCursor.setViewBinder(new SimpleCursorAdapter.ViewBinder() {

      @Override
      public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        int viewId = view.getId();
        switch(viewId) {
        case R.id.icon:
            // change something related to the icon here
    
  2. using of getView/LayoutInflater:

    public View getView(int position, View convertView, ViewGroup parent) {

        View itemView = null;
    
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) parent.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            itemView = inflater.inflate(R.layout.list_row, null);
        } else {
            itemView = convertView;
        }
    
        ImageView imgViewChecked = (ImageView) itemView
                .findViewById(R.id.icon);
        // change something related to the icon here
    

What is the difference between these two approaches?


Solution

  • You can use both of them to accomplish the same task. The ViewBinder system is added by SimpleCursorAdapter to make things easier for you, so you don't have to write the entire getView code. In fact, SimpleCursorAdapter just implements getView by calling the setViewValue method (along with the standard boilerplate error checking and inflating)

    I've attached the implementation that the Android source code uses for getView in SimpleCursorAdapter:

    public View getView(int position, View convertView, ViewGroup parent) {
      if (!mDataValid) {
        throw new IllegalStateException(
            "this should only be called when the cursor is valid");
      }
      if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position "
            + position);
      }
      View v;
      if (convertView == null) {
        v = newView(mContext, mCursor, parent);
      } else {
        v = convertView;
      }
      bindView(v, mContext, mCursor);
      return v;
    }
    
    
    public void bindView(View view, Context context, Cursor cursor) {
      final ViewBinder binder = mViewBinder;
      final int count = mTo.length;
      final int[] from = mFrom;
      final int[] to = mTo;
    
      for (int i = 0; i < count; i++) {
        final View v = view.findViewById(to[i]);
        if (v != null) {
          boolean bound = false;
          if (binder != null) {
            bound = binder.setViewValue(v, cursor, from[i]);
          }
    
          if (!bound) {
            String text = cursor.getString(from[i]);
            if (text == null) {
              text = "";
            }
    
            if (v instanceof TextView) {
              setViewText((TextView) v, text);
            } else if (v instanceof ImageView) {
              setViewImage((ImageView) v, text);
            } else {
              throw new IllegalStateException(
                  v.getClass().getName()
                      + " is not a "
                      + " view that can be bounds by this SimpleCursorAdapter");
            }
          }
        }
      }
    }