Listview, onItemClickListener and EditText

5
我有一个带有EditText的ListView。实际上,当我触摸ListView的元素时,EditText会获得焦点并弹出键盘。很好。 问题是,我想通过ListView的onItemClickListener对此EditText进行操作,但似乎我的代码从未进入此方法。 我尝试了一些setDescendantFocusability来解决这个问题,但没有解决。 非常感谢。
public class NoteAdapter extends BaseAdapter {

private ArrayList<String> notes;
private LayoutInflater inflater;
private Context context;

public NoteAdapter(Context context, ArrayList<String> notes) {
    inflater = LayoutInflater.from(context);
    this.notes = notes;
    this.context = context;
}

public int getCount() {
    // TODO Auto-generated method stub
    return notes.size();
}

public Object getItem(int position) {
    // TODO Auto-generated method stub
    return notes.get(position);
}

public long getItemId(int id) {
    // TODO Auto-generated method stub
    return id;
}


private class ViewHolder {
    EditText note;
}

public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    ViewHolder holder;
    if(convertView == null) {
        holder = new ViewHolder();
        convertView = inflater.inflate(R.layout.listenote, null);
        holder.note = (EditText)convertView.findViewById(R.id.note);


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

    holder.note.setText(notes.get(position));

    return convertView;


}


}

我的主要活动

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    notes = new ArrayList<String>();
    for(int i=0; i< 10; i++)
        notes.add("note"+i);
    EditTextSelected = null;

    adapter = new NoteAdapter(this, notes);
    lv1 = ((ListView)findViewById(R.id.listeNote));
    lv1.setAdapter(adapter);
    lv1.setClickable(true);

    lv1.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> a, View v, int position, long id) {
            Toast t = Toast.makeText(FastItActivity.this, "hello", 200);
            t.show();

        }
    });

listenote.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="@+id/widget1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">


    <EditText
    android:id="@+id/note"
    android:textColor="@color/black"
    android:textSize="12dp"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:padding="5dp"
    android:inputType="textMultiLine"
    android:scrollHorizontally="false"
    android:gravity="top|left"
    android:ems="10"
    android:layout_margin="10dp" 
    android:background="@drawable/fond_note"
    />



 </TableLayout>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="@+id/widget1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/wooden_top"

>

<ListView 
    android:id="@+id/listeNote"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:background="@android:color/transparent"
    android:cacheColorHint="#00000000"
    android:isScrollContainer="false"
    android:divider="#00000000"

    >
</ListView>


</TableLayout>

请描述您想要看到的行为,用户正在做什么?也许您不需要连接ListViewonClickListenerEditText的焦点。 - Ilya Blokh
我希望当用户点击列表中的项目时,键盘出现,我可以更改所选注释的背景颜色,修改高度(包装内容),等等... 当然,实际上,我只是尝试捕获事件(使用toast)。 - Dahevos
为什么需要键盘呢?例如,当单击项目时显示上下文菜单,然后选择编辑选项(更改颜色、高度等)。 - Ilya Blokh
抱歉我的英语不好,我想表达的是用户点击一个项目(我的列表视图中的每一行=编辑文本),然后系统会更改所选注释的颜色和高度。这就是为什么我想在我的主活动中使用setOnItemClickListener捕获事件。实际上,当用户触摸列表视图上的项目时,键盘会出现以便在编辑文本中编辑文本。这正是我想让系统做的,但我还希望系统修改所选编辑文本的某些属性。 - Dahevos
你为什么不使用EditTextOnClickListener处理程序?在EditTextonClick方法中实现你的修改。 - Ilya Blokh
4个回答

2

将您的修改从 ListViewonItemClickListener 移动到您的 EditTextonClickListener 中。

NoteAdaptergetView 中:

holder.note = (EditText)convertView.findViewById(R.id.note);
holder.note.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //do something
        }

    });

或者尝试这个:
holder.note.setOnFocusListener(new View.OnFocusListener(){
@Override    
public void onFocus(){
   //do something
   }
}

getView方法有position参数,因此您可以区分所单击的EditText(如果需要对不同的EditTexts执行不同的操作)


谢谢,我已经这样做了。问题现在是,只有在我双击一个项目时才会出现onClick事件。实际上,第一次点击打开键盘,但setOnCLickListener没有“激活”。如果我再次单击edittext,我最终会得到onClickListene“活动”。如何使我的onClick可以在第一次单击时直接激活?(因此,通过一次单击,键盘出现并处理事件) - Dahevos

0
我找到的解决方案是在EditText和TextView上叠加,并交替设置两者的gone/visible属性,这样当EditText被隐藏时就不会引发错误了。

0

问题在于按钮本身就是管理事件的按钮。我已经这样做了,但现在当我在EditText上点击时间时,键盘会弹出,我需要再次点击EditText才能触发事件。此外,我更喜欢在ListView上管理此事件。无论如何,还是谢谢。 - Dahevos
抱歉,我花了一些时间将代码格式化以适应stackoverflow。关于setDescendat,我在发布的代码中将其删除了,因为它没有起到作用。谢谢。 - Dahevos

0
我曾尝试解决一个类似的问题: 当你在列表项中嵌入多个视图时,哪个项目被选中了?!
我拒绝为列表中的每个项目创建一个新的监听器。我无法想象在这样一个资源受限的平台上扩展性会如何。但是,我发现你可以通过将EditText特化为在onClick中设置和检索所选索引来解决这个问题。
定义你的特化:
package userInterface;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;

public class IndexedEditText extends EditText {
    public int listIndex;

    public IndexedEditText(Context context) {
        super(context);
    }

    public IndexedEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public IndexedEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}

在列表item的XML声明中,将您的EditText替换为您专门的类。确保正确获取到新类的路径(在我的情况下是userInterface.IndexedEditText)。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <userInterface.IndexedEditText
        android:id="@+id/et_first_item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:hint="@string/select"
        android:inputType="none" />

    <!-- other views -->


</RelativeLayout>

getView 中设置 listIndex,并为每个 IndexedEditText 实例设置您的 OnClickListener

public abstract class EditTextPairArrayAdapter <T> extends ArrayAdapter<T> {

    LayoutInflater inflater;

    static class ViewHolder {
        private WeakReference<IndexedEditText>  name;
        private WeakReference<EditText>  notes;

        public ViewHolder(IndexedEditText tv, EditText et) {
            name = new WeakReference<IndexedEditText>(tv);
            notes = new WeakReference<EditText>(et);
        }
    }


    int textViewId;
    int editTextId;
    int listItemId;
    List<T> list = null;
    WeakReference<Context> contextRef;


    //context is Activity that instantiates this array adapter
    //resourceId is the layout xml ID for your special row
    //textViewResourceId is any TextView ID in your special row xml def
    //editTextResourceId means nothing in this context
    //objects is the initial list of objects to present in UI
    public EditTextPairArrayAdapter(Context context, int resourceId, int textViewResourceId, int editTextResourceId, List<T> objects)  {
        super(context, resourceId, textViewResourceId, objects);

        this.listItemId = resourceId;
        this.textViewId = textViewResourceId;
        this.editTextId= editTextResourceId;
        this.list = objects;
        this.contextRef = new WeakReference<Context>(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {
        View       view       = null;
        ViewHolder viewHolder = null;

        if (convertView == null) {
            if(inflater == null)
                inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(listItemId, null);

            IndexedEditText text = (IndexedEditText)view.findViewById(textViewId);
            EditText notes = (EditText) view.findViewById(editTextId);

            text.listIndex = position;
                    //Special sauce

            if(contextRef != null && contextRef.get() != null && (contextRef.get() instanceof View.OnClickListener)) {
                text.setOnClickListener((View.OnClickListener) contextRef.get());
            }

            viewHolder = new ViewHolder(text, notes);

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


        Titem = this.getItem(position);
        if(item != null) {
            //special sauce
        }

        return view;
    }

    //add abstract methods for implementations to define special sauce
}

最后,在实现OnClickListener的Activity中:

public void onClick(View v) {
    if(v instanceof IndexedEditText) {
        Object obj = myList.get(((IndexedEditText)v).listIndex);
        //do stuff with obj         
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接