ListView不显示文本但显示数字(使用的SimpleAdapter)

时间:2016-01-16 08:04:03

标签: java android listview simpleadapter

所以我正在创建一个待办事项应用程序,我是java编程和Android Studio的新手,所以我希望你能忍受我。

这是我的MainActivity包含一个SimpleAdapter来显示列表。

    ListView lv;
    ArrayList<HashMap<String, String>> list;
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_listview_main_activity);
    lv=(ListView)findViewById(R.id.listingtasks);

    DBconnector db=new DBconnector(this);
    list=new ArrayList<HashMap<String,String>>();
    list=db.display();
    String[] from=new String[]{"_id","task"};
    int[] to=new int[]{R.id.id,R.id.tasknamecustom1};

    ListAdapter ad;
    ad = new SimpleAdapter(listview_main_activity.this,list, R.layout.custom,from,to);
    lv.setAdapter(ad);

DBconnector类从SQLiteOpenHelper类扩展,包含在SQLiteDatabase中插入和显示记录的方法。这是DBconnector类:

public class DBconnector extends SQLiteOpenHelper {

public Cursor cr;

public DBconnector(Context context) {
    super(context, "DATABASE", null, 1);
}



@Override
public void onCreate(SQLiteDatabase db) {
    String sqlquery = "CREATE TABLE TASKTABLE(_id INTEGER PRIMARY KEY AUTOINCREMENT, task TEXT);";
    db.execSQL(sqlquery);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    String sqlqueryupgrade = "DROP TABLE IF EXISTS TASKTABLE;";
    db.execSQL(sqlqueryupgrade);
    onCreate(db);
}

这是DBconnector类中的显示方法:

 public ArrayList<HashMap<String,String>> display() {

    ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
    SQLiteDatabase sb = this.getReadableDatabase();
    String sql = "SELECT * FROM TASKTABLE;";
    cr = sb.rawQuery(sql, null); //takes cursor to a position before the first record
    if (cr.moveToFirst()) {
        do {
            HashMap<String,String> hm = new HashMap<String,String>();

            hm.put("_id", cr.getString(0));
            hm.put("task", cr.getString(1));
            list.add(hm);


        } while (cr.moveToNext());


    }

    return list;

}

这是custom.xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:text="Small Text"
    android:id="@+id/id" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Large Text"
    android:id="@+id/tasknamecustom1" />

没有语法错误。我没有找到任何红色下划线,应用程序在我的手机上运行。唯一的问题是我的主要活动的列表视图正确显示了任务的数量,但没有显示任务本身的文本。

这是SimpleAdapter类:

public class SimpleAdapter extends BaseAdapter implements Filterable,      ThemedSpinnerAdapter {
private final LayoutInflater mInflater;

private int[] mTo;
private String[] mFrom;
private ViewBinder mViewBinder;

private List<? extends Map<String, ?>> mData;

private int mResource;
private int mDropDownResource;

/** Layout inflater used for {@link #getDropDownView(int, View, ViewGroup)}. */
private LayoutInflater mDropDownInflater;

private SimpleFilter mFilter;
private ArrayList<Map<String, ?>> mUnfilteredData;

/**
 * Constructor
 *
 * @param context The context where the View associated with this SimpleAdapter is running
 * @param data A List of Maps. Each entry in the List corresponds to one row in the list. The
 *        Maps contain the data for each row, and should include all the entries specified in
 *        "from"
 * @param resource Resource identifier of a view layout that defines the views for this list
 *        item. The layout file should include at least those named views defined in "to"
 * @param from A list of column names that will be added to the Map associated with each
 *        item.
 * @param to The views that should display column in the "from" parameter. These should all be
 *        TextViews. The first N views in this list are given the values of the first N columns
 *        in the from parameter.
 */
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,
        @LayoutRes int resource, String[] from, @IdRes int[] to) {
    mData = data;
    mResource = mDropDownResource = resource;
    mFrom = from;
    mTo = to;
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

/**
 * @see android.widget.Adapter#getCount()
 */
public int getCount() {
    return mData.size();
}

/**
 * @see android.widget.Adapter#getItem(int)
 */
public Object getItem(int position) {
    return mData.get(position);
}

/**
 * @see android.widget.Adapter#getItemId(int)
 */
public long getItemId(int position) {
    return position;
}

/**
 * @see android.widget.Adapter#getView(int, View, ViewGroup)
 */
public View getView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(mInflater, position, convertView, parent, mResource);
}

private View createViewFromResource(LayoutInflater inflater, int position, View convertView,
        ViewGroup parent, int resource) {
    View v;
    if (convertView == null) {
        v = inflater.inflate(resource, parent, false);
    } else {
        v = convertView;
    }

    bindView(position, v);

    return v;
}

/**
 * <p>Sets the layout resource to create the drop down views.</p>
 *
 * @param resource the layout resource defining the drop down views
 * @see #getDropDownView(int, android.view.View, android.view.ViewGroup)
 */
public void setDropDownViewResource(int resource) {
    mDropDownResource = resource;
}

/**
 * Sets the {@link android.content.res.Resources.Theme} against which drop-down views are
 * inflated.
 * <p>
 * By default, drop-down views are inflated against the theme of the
 * {@link Context} passed to the adapter's constructor.
 *
 * @param theme the theme against which to inflate drop-down views or
 *              {@code null} to use the theme from the adapter's context
 * @see #getDropDownView(int, View, ViewGroup)
 */
@Override
public void setDropDownViewTheme(Resources.Theme theme) {
    if (theme == null) {
        mDropDownInflater = null;
    } else if (theme == mInflater.getContext().getTheme()) {
        mDropDownInflater = mInflater;
    } else {
        final Context context = new ContextThemeWrapper(mInflater.getContext(), theme);
        mDropDownInflater = LayoutInflater.from(context);
    }
}

@Override
public Resources.Theme getDropDownViewTheme() {
    return mDropDownInflater == null ? null : mDropDownInflater.getContext().getTheme();
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    final LayoutInflater inflater = mDropDownInflater == null ? mInflater : mDropDownInflater;
    return createViewFromResource(inflater, position, convertView, parent, mDropDownResource);
}

private void bindView(int position, View view) {
    final Map dataSet = mData.get(position);
    if (dataSet == null) {
        return;
    }

    final ViewBinder binder = mViewBinder;
    final String[] from = mFrom;
    final int[] to = mTo;
    final int count = to.length;

    for (int i = 0; i < count; i++) {
        final View v = view.findViewById(to[i]);
        if (v != null) {
            final Object data = dataSet.get(from[i]);
            String text = data == null ? "" : data.toString();
            if (text == null) {
                text = "";
            }

            boolean bound = false;
            if (binder != null) {
                bound = binder.setViewValue(v, data, text);
            }

            if (!bound) {
                if (v instanceof Checkable) {
                    if (data instanceof Boolean) {
                        ((Checkable) v).setChecked((Boolean) data);
                    } else if (v instanceof TextView) {
                        // Note: keep the instanceof TextView check at the bottom of these
                        // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                        setViewText((TextView) v, text);
                    } else {
                        throw new IllegalStateException(v.getClass().getName() +
                                " should be bound to a Boolean, not a " +
                                (data == null ? "<unknown type>" : data.getClass()));
                    }
                } else if (v instanceof TextView) {
                    // Note: keep the instanceof TextView check at the bottom of these
                    // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                    setViewText((TextView) v, text);
                } else if (v instanceof ImageView) {
                    if (data instanceof Integer) {
                        setViewImage((ImageView) v, (Integer) data);                            
                    } else {
                        setViewImage((ImageView) v, text);
                    }
                } else {
                    throw new IllegalStateException(v.getClass().getName() + " is not a " +
                            " view that can be bounds by this SimpleAdapter");
                }
            }
        }
    }
}

/**
 * Returns the {@link ViewBinder} used to bind data to views.
 *
 * @return a ViewBinder or null if the binder does not exist
 *
 * @see #setViewBinder(android.widget.SimpleAdapter.ViewBinder)
 */
public ViewBinder getViewBinder() {
    return mViewBinder;
}

/**
 * Sets the binder used to bind data to views.
 *
 * @param viewBinder the binder used to bind data to views, can be null to
 *        remove the existing binder
 *
 * @see #getViewBinder()
 */
public void setViewBinder(ViewBinder viewBinder) {
    mViewBinder = viewBinder;
}

/**
 * Called by bindView() to set the image for an ImageView but only if
 * there is no existing ViewBinder or if the existing ViewBinder cannot
 * handle binding to an ImageView.
 *
 * This method is called instead of {@link #setViewImage(ImageView, String)}
 * if the supplied data is an int or Integer.
 *
 * @param v ImageView to receive an image
 * @param value the value retrieved from the data set
 *
 * @see #setViewImage(ImageView, String)
 */
public void setViewImage(ImageView v, int value) {
    v.setImageResource(value);
}

/**
 * Called by bindView() to set the image for an ImageView but only if
 * there is no existing ViewBinder or if the existing ViewBinder cannot
 * handle binding to an ImageView.
 *
 * By default, the value will be treated as an image resource. If the
 * value cannot be used as an image resource, the value is used as an
 * image Uri.
 *
 * This method is called instead of {@link #setViewImage(ImageView, int)}
 * if the supplied data is not an int or Integer.
 *
 * @param v ImageView to receive an image
 * @param value the value retrieved from the data set
 *
 * @see #setViewImage(ImageView, int) 
 */
public void setViewImage(ImageView v, String value) {
    try {
        v.setImageResource(Integer.parseInt(value));
    } catch (NumberFormatException nfe) {
        v.setImageURI(Uri.parse(value));
    }
}

/**
 * Called by bindView() to set the text for a TextView but only if
 * there is no existing ViewBinder or if the existing ViewBinder cannot
 * handle binding to a TextView.
 *
 * @param v TextView to receive text
 * @param text the text to be set for the TextView
 */
public void setViewText(TextView v, String text) {
    v.setText(text);
}

public Filter getFilter() {
    if (mFilter == null) {
        mFilter = new SimpleFilter();
    }
    return mFilter;
}

/**
 * This class can be used by external clients of SimpleAdapter to bind
 * values to views.
 *
 * You should use this class to bind values to views that are not
 * directly supported by SimpleAdapter or to change the way binding
 * occurs for views supported by SimpleAdapter.
 *
 * @see SimpleAdapter#setViewImage(ImageView, int)
 * @see SimpleAdapter#setViewImage(ImageView, String)
 * @see SimpleAdapter#setViewText(TextView, String)
 */
public static interface ViewBinder {
    /**
     * Binds the specified data to the specified view.
     *
     * When binding is handled by this ViewBinder, this method must return true.
     * If this method returns false, SimpleAdapter will attempts to handle
     * the binding on its own.
     *
     * @param view the view to bind the data to
     * @param data the data to bind to the view
     * @param textRepresentation a safe String representation of the supplied data:
     *        it is either the result of data.toString() or an empty String but it
     *        is never null
     *
     * @return true if the data was bound to the view, false otherwise
     */
    boolean setViewValue(View view, Object data, String textRepresentation);
}

/**
 * <p>An array filters constrains the content of the array adapter with
 * a prefix. Each item that does not start with the supplied prefix
 * is removed from the list.</p>
 */
private class SimpleFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence prefix) {
        FilterResults results = new FilterResults();

        if (mUnfilteredData == null) {
            mUnfilteredData = new ArrayList<Map<String, ?>>(mData);
        }

        if (prefix == null || prefix.length() == 0) {
            ArrayList<Map<String, ?>> list = mUnfilteredData;
            results.values = list;
            results.count = list.size();
        } else {
            String prefixString = prefix.toString().toLowerCase();

            ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;
            int count = unfilteredValues.size();

            ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count);

            for (int i = 0; i < count; i++) {
                Map<String, ?> h = unfilteredValues.get(i);
                if (h != null) {

                    int len = mTo.length;

                    for (int j=0; j<len; j++) {
                        String str =  (String)h.get(mFrom[j]);

                        String[] words = str.split(" ");
                        int wordCount = words.length;

                        for (int k = 0; k < wordCount; k++) {
                            String word = words[k];

                            if (word.toLowerCase().startsWith(prefixString)) {
                                newValues.add(h);
                                break;
                            }
                        }
                    }
                }
            }

            results.values = newValues;
            results.count = newValues.size();
        }

        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        //noinspection unchecked
        mData = (List<Map<String, ?>>) results.values;
        if (results.count > 0) {
            notifyDataSetChanged();
        } else {
            notifyDataSetInvalidated();
        }
    }
}

}

请有人请帮帮我吗? 谢谢!

1 个答案:

答案 0 :(得分:0)

嘿首先用显示方法中的DBConnector替换此代码。

hm.put("_id", cr.getString(0));

hm.put("_id", cr.getInt(0)+"");

现在发布Simple Adapter的getView()方法,或整个类,以便我可以进一步帮助你。

okk尝试替换

     String text = data == null ? "" : data.toString();

     String text = data == null ? "" : (String)data;

将此代码放入

  View v;
   if (convertView == null) {
    v = inflater.inflate(resource, parent, false);
    } else {
    v = convertView;
    }

   bindView(position, v);

    return v;

进入

  @Override
  public View getDropDownView(int position, View convertView, ViewGroup        parent) {
View v;
if (convertView == null) {
    v = inflater.inflate(resource, parent, false);
} else {
    v = convertView;
}

bindView(position, v);

return v;

}

希望这对你有用。

相关问题