如何在长的自定义列表视图中滚动时跟踪项目的位置

维维克·沃德(Vivek Warde)

从数据库以listview的形式显示的数据(此处为listview,其中的标头已禁用标头的onClick)。

我试图从显示所选项目的描述positiongetView()该列表非常大,因此它在滚动时会动态分配视图,并在滚动position后给出错误的值

我观看了Google I / O 2010-ListView视频的世界,它阐明了这些内容

因此,我认为我需要实现notifyDataSetChanged()或者onScroll()onScrollStateChanged()方法。

但是如何?

代码:

public class MainActivity1 extends ListActivity implements OnTouchListener{

private MyCustomAdapter mAdapter;
Activity temp = this;
String []s = new String[500];
ArrayList<GS> q = new ArrayList<GS>();
CustomAdapter adapter;
ListView lv;
int c=1;

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

 DBAdapter db = DBAdapter.getDBAdapter(getApplicationContext());
    if (!db.checkDatabase()) 
    {
        db.createDatabase(getApplicationContext());
    }
    db.openDatabase();

    q = db.getData();

    mAdapter = new MyCustomAdapter();
    mAdapter.addSeparatorItem(q.get(0).getA_name());
    mAdapter.addItem(q.get(0).getAS_name());
    for (int i = 1; i < 460; i++) {

        if (!(q.get(i).getA_name().trim().equals(q.get(i-1).getA_name().trim()))) {
            mAdapter.addSeparatorItem(q.get(i).getA_name());
            c++;
        }
        mAdapter.addItem(q.get(i).getAS_name());

    }

    setListAdapter(mAdapter);        

}
 //Adapter Class
 private class MyCustomAdapter extends BaseAdapter {

    private static final int TYPE_ITEM = 0;
    private static final int TYPE_SEPARATOR = 1;
    private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

    private ArrayList<String> mData = new ArrayList<String>();
    private LayoutInflater mInflater;

    private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();

    public MyCustomAdapter() {
        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void addItem(final String item) {
        mData.add(item);
        notifyDataSetChanged();
    }

    public void addSeparatorItem(final String item) {
        mData.add(item);
        // save separator position
        mSeparatorsSet.add(mData.size() - 1);
        notifyDataSetChanged();
    }

    @Override
    public int getItemViewType(int position) {
        return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
    }

    @Override
    public int getViewTypeCount() {
        return TYPE_MAX_COUNT;
    }

    public int getCount() {
        return mData.size();
    }

    public String getItem(int position) {
        return mData.get(position);
    }

    public long getItemId(int position) {
        Log.v("getItemId Position", ""+position);
        return position;

    }

            public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        int type = getItemViewType(position);
     //   System.out.println("getView " + position + " " + convertView + " type = " + type);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {
            case TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.activity_main1, null);
                holder.textView = (TextView)convertView.findViewById(R.id.text);

                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.activity_main2, null);
                holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
                count++;
                break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        holder.textView.setText(mData.get(position));

        // We set the OnClickListener here because it is unique to every
        // item. Although views can be recycled & reused, an OnClickListener cannot be.
        if (type == TYPE_ITEM) {
            holder.textView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder x = new AlertDialog.Builder(
                                temp);
                        Log.v("position",""+position);
                               x.setIcon(R.drawable.ic_launcher)
                                .setTitle(q.get(position-count).getAS_name())
                                .setMessage(q.get(position-count).getDesc_art())
                                .setCancelable(true)
                                .setPositiveButton("OK",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface arg,
                                                    int arg1) {
                                            }
                                        });
                               AlertDialog a = x.create();
                        a.show();
                    }
                });
           } else {
            holder.textView.setOnClickListener(null);
            count++;
        }   

        return convertView;
    }
}

public static class ViewHolder {
    public TextView textView;
}

  public boolean onTouch(View v, MotionEvent event) {
 // TODO Auto-generated method stub
  return false;
 }
}

所以,我试图单击时在Alertdialog中显示所选项目的TYPE_ITEM描述。每个TYPE_ITEM的描述顺序存储在数据库中。因此,我需要跟踪TYPE_ITEM的位置(意味着建立索引),以便从数据库中获取数据。我希望你现在了解我的问题!

顺便说一句,我试图在getView()其中使用一个count变量,但是如果我们再次向上滚动(在这种情况下,count应该减少),该怎么办我希望您现在了解问题&我认为我们应该实现notifyDataSetChanged或onScroll,onScrollStateChanged方法。

如果问题不清楚,那么您可以在评论中问我

请帮助!

维克拉姆

您需要做的就是将OnClickListeneron的设置移动holder.textview

这里的问题是:

:由于您在if (convertView == null)块中设置了OnClickListener ,因此当convertView不为null时,它不会更改因此,positioninAlertDialog使用的是您convertView null时设置的

:解决方案是在每次处理职位时都设置OnClickListener-我们不在乎视图是否被回收!!!我们需要重置OnClickListener以反映正确/当前位置。

:尽管我们从来没有在item为时在holder.textview上设置OnClickListener,但是使用可以TYPE_SEPARATOR安全地删除OnClickListener holder.textview.setOnClickListener(null)

请尝试下面的更新代码。我希望这里的逻辑很清楚。

//Adapter Class
private class MyCustomAdapter extends BaseAdapter {

    ....
    ....     
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        int type = getItemViewType(position);
        System.out.println("getView " + position + " " + convertView + " type = " + type);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {
            case TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.activity_main1, null);
                holder.textView = (TextView)convertView.findViewById(R.id.text);
                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.activity_main2, null);
                holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
                break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        holder.textView.setText(mData.get(position));

        // We set the OnClickListener here because it is unique to every
        // item. Although views can be recycled & reused, an OnClickListener cannot be.
        if (type == TYPE_ITEM) {
            holder.textView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder x = new AlertDialog.Builder(
                                temp);
                        Log.v("position",""+position);
                               x.setIcon(R.drawable.ic_launcher)
                                .setTitle(q.get(position-1).getAS_name())
                                .setMessage(q.get(position-1).getDesc_art())
                                .setCancelable(true)
                                .setPositiveButton("OK",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface arg,
                                                    int arg1) {

                                            }
                                        });
                        AlertDialog a = x.create();
                        a.show();
                    }
              });
        } else {
            holder.textview.setOnClickListener(null);
        }   

        return convertView;
    }

    ....
    ....

}

编辑:

包装器类(可以实现为的内部类,MainActivity1也可以独立地实现):

public class ContentWrapper {

    private String mItem, mItemDescription;

    public ContentWrapper(String item, String itemDescription) {
        mItem = item;
        mItemDescription = itemDescription;
    }

    public String getItem() {
        return mItem;
    }

    public String getItemDescription() {
        return mItemDescription;
    }
}

您的数据设置也会更改:

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

    DBAdapter db = DBAdapter.getDBAdapter(getApplicationContext());
    if (!db.checkDatabase()) 
    {
        db.createDatabase(getApplicationContext());
    }
    db.openDatabase();

    q = db.getData();

    mAdapter = new MyCustomAdapter();

    // mAdapter.addSeparatorItem(q.get(0).getA_name());

    // First separator item
    // No description
    mAdapter.addSeparatorItem(new ContentWrapper(q.get(0).getA_name(), null));

    // mAdapter.addItem(q.get(0).getAS_name());

    // First TYPE_ITEM
    // Pass the description
    mAdapter.addItem(new ContentWrapper(q.get(0).getAS_name(), q.get(0).getDesc_art()));


    for (int i = 1; i < 460; i++) {

        if (!(q.get(i).getA_name().trim().equals(q.get(i-1).getA_name().trim()))) {
            // mAdapter.addSeparatorItem(q.get(i).getA_name());
            mAdapter.addSeparatorItem(new ContentWrapper(q.get(i).getA_name(), null));
            c++;
        }

        // mAdapter.addItem(q.get(i).getAS_name());
        mAdapter.addItem(new ContentWrapper(q.get(i).getAS_name(), q.get(i).getDesc_art()));
    }

    setListAdapter(mAdapter);        
}

接下来,我们对适配器进行更改:

// private ArrayList<String> mData = new ArrayList<String>();
private ArrayList<ContentWrapper> mData = new ArrayList<ContentWrapper>();

add*方法

public void addItem(ContentWrapper value) {
    mData.add(value);
    notifyDataSetChanged();
}

public void addSeparatorItem(ContentWrapper value) {
    mData.add(value);
    // save separator position
    mSeparatorsSet.add(mData.size() - 1);
    notifyDataSetChanged();
}

public ContentWrapper getItem(int position) {
    return mData.get(position);
}

getView(...)方法:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    ....
    ....

    holder.textView.setText(mData.get(position).getItem());

    if (type == TYPE_ITEM) {
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog.Builder x = new AlertDialog.Builder(temp);
                Log.v("position",""+position);
                       x.setIcon(R.drawable.ic_launcher)

                        // .setTitle(q.get(position-count).getAS_name())
                        .setTitle(mData.get(position).getItem())

                        // .setMessage(q.get(position-count).getDesc_art())
                        .setMessage(mData.get(position).getItemDescription())

                        .setCancelable(true)
                        .setPositiveButton("OK",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface arg,
                                            int arg1) {
                                    }
                                });
                 AlertDialog a = x.create();
                 a.show();
             }
         });
    } else {
        holder.textView.setOnClickListener(null);
    }
}

就是这样。

[我]认为我们应该实现notifyDataSetChanged或onScroll,onScrollStateChanged方法。

notifyDataSetChanged()用于告诉适配器基础数据已更改,因此需要刷新。例如,如果某项的描述发生更改,则可以在中更新该项mData并调用notifyDataSetChanged()但是根据您的情况(以及代码告诉我的情况),在使用-设置适配器之前,将初始化数据setListAdapter(mAdapter)因此,甚至不需要调用方法notifyDataSetChanged()内部add*notifyDataSetChanged()在将适配器附加到列表视图之前进行调用不会执行任何操作。

onScroll并且onScrollChanged是为了不同的目的。例如,假设您Go To Top of the List在用户滚动到第50个项目时显示一个按钮-在用户向上滚动第50个位置时将其隐藏。在您的情况下,问题在于您试图从两个不同的源(mData,q)获取数据,并且同步出现问题。没有其他的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当我滚动列表视图时,列表视图中项目的位置正在更改

来自分类Dev

滚动列表视图时,列表视图中项目的位置正在更改?

来自分类Dev

如何在自定义列表视图中对项目单击启动不同的活动?

来自分类Dev

在android中滚动列表视图时,文本值会在自定义列表视图中更改?

来自分类Dev

视图持有人和自定义列表视图项目在滚动时被拖曳

来自分类Dev

如何在滚动视图中重新加载自定义视图?

来自分类Dev

如何在Android中具有多个选择的自定义列表视图中获取选中的项目ID

来自分类Dev

Android-如何在此列表视图中使用自定义列表视图

来自分类Dev

单击按钮从自定义列表视图中删除项目

来自分类Dev

从自定义列表视图中获取过滤的项目时,IndexOutOfBound

来自分类Dev

如果我们连续有很多文本视图,如何在自定义列表视图中单击该文本视图时更改文本视图的文本?

来自分类Dev

从列表视图中删除自定义列表视图中的项目,单击按钮

来自分类Dev

如何在地图视图中显示带有自定义注释的多个位置

来自分类Dev

自定义列表视图滚动时应用崩溃

来自分类Dev

Android自定义列表视图滚动时加载缓慢

来自分类Dev

如何在自定义视图之外跟踪点击

来自分类Dev

如何自定义列表视图以使行项目的第一和第二位置具有不同的布局?

来自分类Dev

Android:如何在自定义列表视图中添加列标题

来自分类Dev

如何在自定义列表视图中添加静态标题图片?

来自分类Dev

如何在自定义列表视图中启动动画

来自分类Dev

如何在Android的自定义列表视图中ser读取未读消息

来自分类Dev

如何在自定义列表视图中添加静态标题图片?

来自分类Dev

如何在使用Volley创建的自定义列表视图中删除html标签

来自分类Dev

如何在具有透明背景的自定义列表视图中显示图像

来自分类Dev

如何在自定义列表视图中共享外部图像?

来自分类Dev

android-从列表视图中获取带有自定义项目视图的项目

来自分类Dev

如何在列表视图中显示广告横幅时管理项目位置

来自分类Dev

如何在按钮单击时在自定义视图中绘制圆圈

来自分类Dev

如何在ui视图中显示自定义指令?

Related 相关文章

  1. 1

    当我滚动列表视图时,列表视图中项目的位置正在更改

  2. 2

    滚动列表视图时,列表视图中项目的位置正在更改?

  3. 3

    如何在自定义列表视图中对项目单击启动不同的活动?

  4. 4

    在android中滚动列表视图时,文本值会在自定义列表视图中更改?

  5. 5

    视图持有人和自定义列表视图项目在滚动时被拖曳

  6. 6

    如何在滚动视图中重新加载自定义视图?

  7. 7

    如何在Android中具有多个选择的自定义列表视图中获取选中的项目ID

  8. 8

    Android-如何在此列表视图中使用自定义列表视图

  9. 9

    单击按钮从自定义列表视图中删除项目

  10. 10

    从自定义列表视图中获取过滤的项目时,IndexOutOfBound

  11. 11

    如果我们连续有很多文本视图,如何在自定义列表视图中单击该文本视图时更改文本视图的文本?

  12. 12

    从列表视图中删除自定义列表视图中的项目,单击按钮

  13. 13

    如何在地图视图中显示带有自定义注释的多个位置

  14. 14

    自定义列表视图滚动时应用崩溃

  15. 15

    Android自定义列表视图滚动时加载缓慢

  16. 16

    如何在自定义视图之外跟踪点击

  17. 17

    如何自定义列表视图以使行项目的第一和第二位置具有不同的布局?

  18. 18

    Android:如何在自定义列表视图中添加列标题

  19. 19

    如何在自定义列表视图中添加静态标题图片?

  20. 20

    如何在自定义列表视图中启动动画

  21. 21

    如何在Android的自定义列表视图中ser读取未读消息

  22. 22

    如何在自定义列表视图中添加静态标题图片?

  23. 23

    如何在使用Volley创建的自定义列表视图中删除html标签

  24. 24

    如何在具有透明背景的自定义列表视图中显示图像

  25. 25

    如何在自定义列表视图中共享外部图像?

  26. 26

    android-从列表视图中获取带有自定义项目视图的项目

  27. 27

    如何在列表视图中显示广告横幅时管理项目位置

  28. 28

    如何在按钮单击时在自定义视图中绘制圆圈

  29. 29

    如何在ui视图中显示自定义指令?

热门标签

归档