安卓:问题NewView的和bindView定制SimpleCursorAdapter [英] Android: Issue with newView and bindView in custom SimpleCursorAdapter

查看:136
本文介绍了安卓:问题NewView的和bindView定制SimpleCursorAdapter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个自定义SimpleCursorAdapter从唯一的例子,我发现。

当我L​​istActivity被调用,NewView的和bindView被称为为每一位我的数据库条目,并再次呼吁每个条目。我有几个问题:

-is的例子正确的(如果不是,我在哪里可以找到一个)?

- 如果bindView电话总是$由NewView的电话,为什么做同样在这两个功能?pceded p $

- 为什么是序列NewView的-bindView调用两次为每一个项目?

- 为什么一些CursorAdapter的例子​​使用getView代替NewView的和bindView?

基本上,应该如何SimpleCursorAdapter使用,这有什么错我的code?

感谢


ListActivity

 公共类ContactSelection扩展ListActivity {

    私人WhipemDBAdapter mDbHelper;
    私人FriendAdapter friendAdapter;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);

        mDbHelper =新WhipemDBAdapter(本);
        mDbHelper.open();

        的setContentView(R.layout.contact_list);

        光标C = mDbHelper.fetchAllFriends();
        startManagingCursor(C);
        的String []从=新的String [] {};
        INT []到=新INT [] {};

        this.friendAdapter =新FriendAdapter(这一点,R.layout.contact_row,C,从,到);
        setListAdapter(this.friendAdapter);

        。getListView()setItemsCanFocus(假);
        。getListView()setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    }

    @覆盖
    保护无效onResume(){
        super.onResume();
        mDbHelper.open();
    }

    @覆盖
    保护无效的onPause(){
        super.onPause();
        mDbHelper.close();
    }
}
 

自定义SimpleCursorAdapter

 公共类FriendAdapter扩展SimpleCursorAdapter实现OnClickListener {

    私人语境mContext;
    私人诠释mLayout;

    公共FriendAdapter(上下文的背景下,INT布局,光标C,的String []从,INT []键){
        超(背景下,布局,C,从,到);

        this.mContext =背景;
        this.mLayout =布局;
    }

    @覆盖
    公共查看NewView的(上下文的背景下,光标光标的ViewGroup父){

        光标C = getCursor();

        最后LayoutInflater充气= LayoutInflater.from(上下文);
        视图V = inflater.inflate(mLayout,父母,假);

        字符串名称= c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_NAME));
        串fb_id = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_FB_ID));

        TextView的name_text =(TextView中)v.findViewById(R.id.contact_name);
        如果(name_text!= NULL){
            name_text.setText(名称);
        }

        ImageView的IM =(ImageView的)v.findViewById(R.id.contact_pic);
        可绘制绘制= LoadImageFromWebOperations(http://graph.facebook.com/+ fb_id +/图片);
        如果(我!= NULL){
            im.setImageDrawable(绘制);
        }

        复选框B检查=(复选框)v.findViewById(R.id.checkbox);
        如果(我!= NULL){
            bCheck.setTag(fb_id);
        }

        如果(((GlobalVars)mContext.getApplicationContext())。isFriendSelected(fb_id))
            bCheck.setChecked(真正的);

        bCheck.setOnClickListener(本);

        返回伏;
    }

    @覆盖
    公共无效bindView(视图V,上下文的背景下,光标C){

         字符串名称= c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_NAME));
         串fb_id = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_FB_ID));


         TextView的name_text =(TextView中)v.findViewById(R.id.contact_name);
         如果(name_text!= NULL){
             name_text.setText(名称);
         }

        ImageView的IM =(ImageView的)v.findViewById(R.id.contact_pic);
        可绘制绘制= LoadImageFromWebOperations(http://graph.facebook.com/+ fb_id +/图片);
        如果(我!= NULL){
            im.setImageDrawable(绘制);
        }

        复选框B检查=(复选框)v.findViewById(R.id.checkbox);
        如果(我!= NULL){
            bCheck.setTag(fb_id);
        }

        ArrayList的<字符串>花花公子=((GlobalVars)mContext.getApplicationContext())getSelectedFriendList()。

        如果(((GlobalVars)mContext.getApplicationContext())。isFriendSelected(fb_id))
            bCheck.setChecked(真正的);

        bCheck.setOnClickListener(本);
    }


    @覆盖
    公共无效的onClick(视图v){
        复选框的CBox =(复选框)V;
        字符串fb_id =(字符串)cBox.getTag();

        如果(cBox.isChecked()){
            如果(!((GlobalVars)mContext.getApplicationContext())。isFriendSelected(fb_id))
                ((GlobalVars)mContext.getApplicationContext())addSelectedFriend(fb_id)。
        } 其他 {
            如果(((GlobalVars)mContext.getApplicationContext())。isFriendSelected(fb_id))
                ((GlobalVars)mContext.getApplicationContext())removeSelectedFriend(fb_id)。
        }

    }

    私人绘制对象LoadImageFromWebOperations(字符串URL)
    {
        尝试
        {
            InputStream的是=(InputStream的)新的网址(URL).getContent();
            绘制对象D = Drawable.createFromStream(是,SRC名);
            返回D组;
        }赶上(例外五){
            的System.out.println(EXC =+ E);
            返回null;
        }
    }

}
 

解决方案

重写 getView()功能为您提供了再利用已经膨胀列表项的可能性(滚动时,是根据目前的观察口滚出列表项的清单来回)。

这样你可以节省大量的内存资源和处理器运行时,由于膨胀是一个相当耗时的操作。对于每一个 convertView 您重新使用您还可以节省GC运行时间(因为垃圾收集器并不一定要收集该特定列表项)。

您还可以创建一个视图集类( ViewHolder 类在下面的例子),这将握在充气列表项为每个视图引用。这样,您就不必每一个你用新值更新列表项的时间找到他们(通常焕滚动列表)。 findViewById()也是一个相当耗时的操作。

此外,我觉得你可以缓存更多的变量,如布局充气,和列索引。一切以节省时间: - )

 私人最终上下文mContext;
私人最终诠释mLayout;
私人最终光标mCursor;
私人最终诠释mNameIndex;
私人最终诠释mIdIndex;
私人最终LayoutInflater mLayoutInflater;

私人final类ViewHolder {
    公共TextView的名称;
    公众ImageView的形象;
    公开复选框复选框;
}

公共FriendAdapter(上下文的背景下,INT布局,光标C,的String []从,INT []键){
    超(背景下,布局,C,从,到);

    this.mContext =背景;
    this.mLayout =布局;
    this.mCursor = C;
    this.mNameIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_NAME);
    this.mIdIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_FB_ID);
    this.mLayoutInflater = LayoutInflater.from(mContext);
}

公共查看getView(INT位置,查看convertView,ViewGroup中父){
    如果(mCursor.moveToPosition(位置)){
        ViewHolder viewHolder;

        如果(convertView == NULL){
            convertView = mLayoutInflater.inflate(mLayout,NULL);

            viewHolder =新ViewHolder();
            viewHolder.name =(TextView中)convertView.findViewById(R.id.contact_name);
            viewHolder.image =(ImageView的)convertView.findViewById(R.id.contact_pic);
            viewHolder.checkBox =(复选框)convertView.findViewById(R.id.checkbox);

            convertView.setTag(viewHolder);
        }
        其他 {
            viewHolder =(ViewHolder)convertView.getTag();
        }

        字符串名称= mCursor.getString(mNameIndex);
        字符串fb_id = mCursor.getString(mIdIndex);
        可绘制绘制= LoadImageFromWebOperations(http://graph.facebook.com/+ fb_id +/图片);
        布尔器isChecked =((GlobalVars)mContext.getApplicationContext())isFriendSelected(fb_id)。

        viewHolder.name.setText(名称);
        viewHolder.image.setImageDrawable(绘制);
        viewHolder.checkBox.setTag(fb_id);
        viewHolder.checkBox.setChecked(器isChecked);
    }

    返回convertView;
}
 

I created a custom SimpleCursorAdapter from one of the only example I found.

When my ListActivity is called, newView and bindView are called for every of my DB entry, and called again for every entry. I've got a few questions:

-is the example right (if not, where can I find one)?

-if bindView call is always preceded by newView call, why doing the same in both functions?

-why is the sequence newView-bindView called twice for every item?

-why some CursorAdapter examples use getView instead of newView and bindView?

Basically, how should SimpleCursorAdapter be used, and what's wrong with my code?

Thanks


ListActivity

public class ContactSelection extends ListActivity {

    private WhipemDBAdapter mDbHelper;
    private FriendAdapter friendAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mDbHelper = new WhipemDBAdapter(this);
        mDbHelper.open();     

        setContentView(R.layout.contact_list);   

        Cursor c = mDbHelper.fetchAllFriends();
        startManagingCursor(c);     
        String[] from = new String[] {};
        int[] to = new int[] {};

        this.friendAdapter = new FriendAdapter(this, R.layout.contact_row, c, from, to);
        setListAdapter(this.friendAdapter);

        getListView().setItemsCanFocus(false);
        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mDbHelper.open();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mDbHelper.close();
    }
}

Custom SimpleCursorAdapter

public class FriendAdapter extends SimpleCursorAdapter implements OnClickListener {

    private Context mContext;
    private int mLayout;

    public FriendAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);

        this.mContext = context;
        this.mLayout = layout;
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        Cursor c = getCursor();

        final LayoutInflater inflater = LayoutInflater.from(context);
        View v = inflater.inflate(mLayout, parent, false);     

        String name = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_NAME));
        String fb_id = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_FB_ID));

        TextView name_text = (TextView) v.findViewById(R.id.contact_name);
        if (name_text != null) {
            name_text.setText(name);
        }

        ImageView im = (ImageView) v.findViewById(R.id.contact_pic);            
        Drawable drawable = LoadImageFromWebOperations("http://graph.facebook.com/"+fb_id+"/picture");
        if (im != null) {
            im.setImageDrawable(drawable);
        }

        CheckBox bCheck = (CheckBox) v.findViewById(R.id.checkbox);
        if (im != null) {
            bCheck.setTag(fb_id);
        }            

        if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id))
            bCheck.setChecked(true);

        bCheck.setOnClickListener(this);

        return v;
    }

    @Override
    public void bindView(View v, Context context, Cursor c) {

         String name = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_NAME));
         String fb_id = c.getString(c.getColumnIndex(WhipemDBAdapter.KEY_FB_ID));


         TextView name_text = (TextView) v.findViewById(R.id.contact_name);
         if (name_text != null) {
             name_text.setText(name);
         }

        ImageView im = (ImageView) v.findViewById(R.id.contact_pic);            
        Drawable drawable = LoadImageFromWebOperations("http://graph.facebook.com/"+fb_id+"/picture");
        if (im != null) {
            im.setImageDrawable(drawable);
        }

        CheckBox bCheck = (CheckBox) v.findViewById(R.id.checkbox);
        if (im != null) {
            bCheck.setTag(fb_id);
        }

        ArrayList<String> dude = ((GlobalVars) mContext.getApplicationContext()).getSelectedFriendList();

        if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id))
            bCheck.setChecked(true);

        bCheck.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        CheckBox cBox = (CheckBox) v;
        String fb_id = (String) cBox.getTag();

        if (cBox.isChecked()) {
            if (!((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id))
                ((GlobalVars) mContext.getApplicationContext()).addSelectedFriend(fb_id);
        } else {
            if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id))
                ((GlobalVars) mContext.getApplicationContext()).removeSelectedFriend(fb_id);
        }

    }

    private Drawable LoadImageFromWebOperations(String url)
    {
        try
        {
            InputStream is = (InputStream) new URL(url).getContent();
            Drawable d = Drawable.createFromStream(is, "src name");
            return d;
        }catch (Exception e) {
            System.out.println("Exc="+e);
            return null;
        }
    }

}

解决方案

Overriding the getView() function gives you the possibility of "re-using" already inflated list items (the list items that are "scrolled out" from the current view port when you scroll your list back and forth).

By doing so you'll save a lot of memory resources and processor run time, since inflating is a quite time consuming operation. For each and every convertView you re-use you also save GC run-time (since the garbage collector doesn't have to collect that specific list item).

You can also create a "view collection" class (the ViewHolder class in the below example) which will hold the references for each view in your inflated list item. This way you don't have to find them each and every time you update a list item with new values (typically whan you scroll the list). findViewById() is also a rather time consuming operation.

Also I think you can cache more variables, like the layout inflater, and the column indices. Everything to save time :-)

private final Context mContext;
private final int mLayout;
private final Cursor mCursor;
private final int mNameIndex;
private final int mIdIndex;
private final LayoutInflater mLayoutInflater;

private final class ViewHolder {
    public TextView name;
    public ImageView image;
    public CheckBox checkBox;
}

public FriendAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
    super(context, layout, c, from, to);

    this.mContext = context;
    this.mLayout = layout;
    this.mCursor = c;
    this.mNameIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_NAME);
    this.mIdIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_FB_ID);
    this.mLayoutInflater = LayoutInflater.from(mContext);
}

public View getView(int position, View convertView, ViewGroup parent) {
    if (mCursor.moveToPosition(position)) {
        ViewHolder viewHolder;

        if (convertView == null) {
            convertView = mLayoutInflater.inflate(mLayout, null);

            viewHolder = new ViewHolder();
            viewHolder.name = (TextView) convertView.findViewById(R.id.contact_name);
            viewHolder.image = (ImageView) convertView.findViewById(R.id.contact_pic);
            viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);

            convertView.setTag(viewHolder);
        }
        else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        String name = mCursor.getString(mNameIndex);
        String fb_id = mCursor.getString(mIdIndex);
        Drawable drawable = LoadImageFromWebOperations("http://graph.facebook.com/"+fb_id+"/picture");
        boolean isChecked = ((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id);

        viewHolder.name.setText(name);
        viewHolder.image.setImageDrawable(drawable);
        viewHolder.checkBox.setTag(fb_id);
        viewHolder.checkBox.setChecked(isChecked);
    }

    return convertView;
}

这篇关于安卓:问题NewView的和bindView定制SimpleCursorAdapter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆