Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android中,如何从onlistitemclick更改单个listview行中小部件的可见性?_Android_Listview_Visibility - Fatal编程技术网

在Android中,如何从onlistitemclick更改单个listview行中小部件的可见性?

在Android中,如何从onlistitemclick更改单个listview行中小部件的可见性?,android,listview,visibility,Android,Listview,Visibility,我的最终目标是将中的信息源从数组更改为光标。这里有一个链接到。其要点是,单击列表中的一行,正文将在列出的标题下打开,然后再次单击它,正文将消失。我不想记住便笺是否打开,也不想通过视图循环保持它打开,也不想在打开一个或任何其他我能想到的奇特排列时关闭所有其他 大多数情况下,一切都正常工作,但当onListItemClick事件处理程序启动、更改可见性以及notifyDataSetChanged()s时,列表会做一些奇怪的事情,包括单击两次以更改可见性,而不重新测量自身,导致列表行每隔三次左右只为自

我的最终目标是将中的信息源从数组更改为光标。这里有一个链接到。其要点是,单击列表中的一行,正文将在列出的标题下打开,然后再次单击它,正文将消失。我不想记住便笺是否打开,也不想通过视图循环保持它打开,也不想在打开一个或任何其他我能想到的奇特排列时关闭所有其他

大多数情况下,一切都正常工作,但当onListItemClick事件处理程序启动、更改可见性以及
notifyDataSetChanged()
s时,列表会做一些奇怪的事情,包括单击两次以更改可见性,而不重新测量自身,导致列表行每隔三次左右只为自身腾出空间

之前的一次尝试导致了一个完美的工作列表,除了单击时,我想隐藏和显示的每一行中的块都会隐藏和显示,教程中的列表工作得非常好,但当然,在所有内容中都使用静态大小,所以只不过是一个模板

我确信问题要么是获取附加到列表行的可见性信息,要么是在设置之后更改它

以下是
onListItemClick

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    ((NotesCursorAdapter) getListAdapter()).toggle(position, v);
}
使用
notescrsoradapter
中的切换方法:

    public void toggle(int position, View view) {
        ViewHolder holder = (ViewHolder) view.getTag();

        holder.mExpanded[position] = !holder.mExpanded[position];
        notifyDataSetChanged();
    }
notescorsoradapter
外部的
ViewHolder

static class ViewHolder {
    public TextView title;
    public TextView body;
    public boolean mExpanded[];
}
以及
notescrsoradapter
本身:

class NotesCursorAdapter extends CursorAdapter {

    private static final int VISIBLE = 0;
    private static final int GONE = 8;

    public NotesCursorAdapter(Context context, Cursor c) {
        super(context, c);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.row, null, true);

        ViewHolder holder = new ViewHolder();
        holder.title = (TextView) rowView
                .findViewById(R.id.title);
        holder.body = (TextView) rowView
                .findViewById(R.id.body);
        holder.mExpanded = new boolean[cursor.getCount()];
        rowView.setTag(holder);

        return rowView;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();

        holder.title.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(DbAdapter.KEY_TITLE))
                + holder.mExpanded[cursor.getPosition()]);
        holder.body.setText(cursor
                .getString(cursor
                        .getColumnIndexOrThrow(DbAdapter.KEY_BODY)));
        holder.body
                .setVisibility(holder.mExpanded[cursor.getPosition()] ? VISIBLE : GONE);

    }

    public void toggle(int position, View view) {
        ViewHolder holder = (ViewHolder) view.getTag();

        holder.mExpanded[position] = !holder.mExpanded[position];
        notifyDataSetChanged();
    }
}
我不知道下一步该往哪里看。我是否需要创建自己的
getView()
方法?我能从
getItem()
中得到有用的东西吗?像这样尝试使用
列表视图
,我是不是疯了


我已经做了更多的调查,代码正在运行,但是点击事件似乎影响了相反的观点。我的意思是,当您单击顶部列表项时,它会影响底部列表项。单击顶部的第二个按钮时,将影响底部的第二个按钮。如果列表项的数量为奇数,则中间的列表项工作正常。在某种程度上,无论我用什么方式来确定我正在影响的视图的id,都会被翻转。listview是否自下而上进行编号?

我刚刚在API演示的List6中实现了类似的功能。我的相机工作得很好(不管怎样,我在使用图像按钮对焦时遇到了麻烦)。我使用了一个简单的游标适配器,但是我想你可以使用游标适配器。我修改了你的代码很多

不知道为什么还要添加View参数,所以我去掉了它

private ArrayList<Boolean> mExpanded;

@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        ((NotesCursorAdapter) getListAdapter()).toggle(position);
    }
这是您的自定义ListAdapter。我不知道你为什么想使用bindView和newView与一个ViewHolder,Android负责bindView和newView。但在这种情况下,您需要使用ViewHolder,因此getView是必要的

private class NotesCursorAdapter extends SimpleCursorAdapter {

private Cursor cursor;
private LayoutInflater inflater;

public NotesCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) {
    super(context, layout, cursor, from, to);
    this.cursor = cursor;
    inflater = LayoutInflater.from(context);
    mExpanded = new ArrayList<Boolean>();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;          
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.row, parent, false);

        populateExpanded();

        holder = new ViewHolder(convertView, mExpanded.get(position));

        convertView.setTag(holder);
    }
    else {
        holder = (ViewHolder) convertView.getTag();
    }
        holder.setTitle(position);
        holder.setBody(position);
        holder.setExpanded(mExpanded.get(position));

        return rowView;
}

private void populateExpanded() {
    // We want our hidden TextView to not be expanded initially
    for (int i = 0; i < cursor.getCount(); i++) {
        mExpanded.add(false);
    }
}

public void toggle(int position) {
if (mExpanded.get(position) == false) {
    mExpanded.set(position, true);
}
else {
    mExpanded.set(position, false);
}
    notifyDataSetChanged();
    }
}

K、 我弄明白了。设置未正确显示,因为ListView有两个层:视图层和数据层。android在ListView中回收视图的方式意味着使用哪个视图来显示数据并不重要。因此,要使用CursorAdapter,视图信息进入newView()方法,来自光标的数据信息进入bindView()方法。这里是固定的东西:

这里没有太多变化,只是传递了需要的信息:

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    ((NotesCursorAdapter) l.getAdapter()).toggle(position);
}
视图持有者仅获取构造视图所需的信息,而不获取视图中的任何信息,包括可见状态:

static class ViewHolder {
    public TextView title;
    public TextView body;
    public Button button;
}
可见状态作为适配器的属性在数组中进行跟踪。视图信息在newView()方法中,数据信息在bindView()方法中。当NOTIFYDATASETCHANGE()启动时,所有视图都将被回收,数据将重新分层。因为视图信息和数据信息是分开的,所以哪个视图与哪个数据匹配并不重要

    class NotesCursorAdapter extends CursorAdapter {

    private boolean[] expandedArray;

    public NotesCursorAdapter(Context context, Cursor c) {
        super(context, c);
        expandedArray = new boolean[c.getCount()];
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.row, parent, false);

        ViewHolder holder = new ViewHolder();
        holder.title= (TextView) rowView
                .findViewById(R.id.title);
        holder.body= (TextView) rowView
                .findViewById(R.id.body);
        holder.button= (Button) rowView
                .findViewById(R.id.button);

        rowView.setTag(holder);
        return rowView;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();

        holder.title.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
        holder.body.setText(cursor.getString(cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
        holder.body
                .setVisibility(expandedArray[cursor.getPosition()] ? View.VISIBLE
                        : View.GONE);
        holder.button
                .setVisibility(expandedArray[cursor.getPosition()] ? View.VISIBLE
                        : View.GONE);
        holder.button.setTag(cursor.getPosition());

    }

    public void toggle(int position) {
        expandedArray[position] = !expandedArray[position];
        notifyDataSetChanged();
    }
}
为完整起见,以下是要在onCreate()、onActivityResult()或需要重新加载列表时调用的ListAdapter映射中的映射:

private void fillData() {
    notesCursor = mDbHelper.fetchAllNotes();
    startManagingCursor(notesCursor);
    NotesCursorAdapter notes = new NotesCursorAdapter(this, notesCursor);
    setListAdapter(notes);
}

我正在努力让你的代码正常工作。在哪里调用setExpanded(),当holder为null时,如何设置holder上数组的大小?我把视图作为一个参数,因为我在尝试不同的东西,所以我让构造函数接受我能得到的任何东西。我使用CursorAdapter而不是SimpleCursorAdapter,因为我最终会做一些不简单的事情,我不认为SimpleCursorAdapter的作用不仅仅是将字符串映射到文本视图和图像视图。CursorAdapter需要newView()和bindView()方法的代码。好的,我修复了一些错误。我创建了一个方法来设置布尔数组的初始值。就像他们在列表6中预定义的那样(但这是一种静态的廉价方式,而不是动态的)。SimpleCrsorAdapter可以做任何你想做的事情。在我的应用程序中,我有一个文本视图(就像你的标题)和一个线性布局,它的可见性已经消失。它包含两个ImageButton(带有onclicklisteners)和一个textview(显示数字)。这很不简单。你到底想以后做什么?我知道了。问题是我在适配器和视图保持架中跟踪扩展视图的状态。一旦我在适配器类中添加了一个布尔数组,然后用它来确定视图的状态,应用程序就开始做一些奇怪的事情,当我从视图保持器中删除可见性布尔值时,它工作得非常好。非常感谢你的帮助。让我尝试一个简单的游标适配器,让我真正了解了getView()/newView()/bindView()系统是如何工作的,也让我真正了解了对象的来源。太棒了!没问题!我遇到这个问题是出于良心,因为我是w
    class NotesCursorAdapter extends CursorAdapter {

    private boolean[] expandedArray;

    public NotesCursorAdapter(Context context, Cursor c) {
        super(context, c);
        expandedArray = new boolean[c.getCount()];
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.row, parent, false);

        ViewHolder holder = new ViewHolder();
        holder.title= (TextView) rowView
                .findViewById(R.id.title);
        holder.body= (TextView) rowView
                .findViewById(R.id.body);
        holder.button= (Button) rowView
                .findViewById(R.id.button);

        rowView.setTag(holder);
        return rowView;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();

        holder.title.setText(cursor.getString(cursor
                .getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
        holder.body.setText(cursor.getString(cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
        holder.body
                .setVisibility(expandedArray[cursor.getPosition()] ? View.VISIBLE
                        : View.GONE);
        holder.button
                .setVisibility(expandedArray[cursor.getPosition()] ? View.VISIBLE
                        : View.GONE);
        holder.button.setTag(cursor.getPosition());

    }

    public void toggle(int position) {
        expandedArray[position] = !expandedArray[position];
        notifyDataSetChanged();
    }
}
private void fillData() {
    notesCursor = mDbHelper.fetchAllNotes();
    startManagingCursor(notesCursor);
    NotesCursorAdapter notes = new NotesCursorAdapter(this, notesCursor);
    setListAdapter(notes);
}