简体   繁体   中英

Unable to listen to setOnItemClickListener in ListView - Android

I have a ListView in my MainActivity which has a customAdapter to it. I am implementing a slider on each of the list items. I have also attached a footerView to my listView. Now my problem is that, the setOnClickListener is not fired, and I am not able to print the position's of the listView. It only print's for the footerView alone, which I have attached.

The code for MainActivity is

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";

    private Context mContext;

    private ListView mainListView;

    private TextView addContact;

    private EditText inputName;

    private List<String> contactList = new ArrayList<String>();

    private MainListAdapter mainAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        mContext = this;

        init();
    }

    private void init() {
        mainListView = (ListView)findViewById(R.id.lv_main);

        initListData();

        View footerView = getLayoutInflater().inflate(R.layout.listview_item_main, null);
        footerView.setBackgroundColor(getResources().getColor(R.color.gold));

        addContact = (TextView)footerView.findViewById(R.id.tv_item_name);
        addContact.setText(getString(R.string.plus));
        mainListView.addFooterView(footerView);

        mainAdapter = new MainListAdapter(mContext, contactList);
        mainListView.setAdapter(mainAdapter);

        mainListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 Log.e(TAG, "on click item " + position);
                if (position == contactList.size()) {
                    addContact.setVisibility(View.GONE);
                    inputName.setVisibility(View.VISIBLE);
                }
            }
        });

        inputName = (EditText)footerView.findViewById(R.id.et_input_name);
        inputName.setOnEditorActionListener(new OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_GO) {
                    InputMethodManager imm = (InputMethodManager)mContext
                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm.isActive()) {
                        imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
                    }
                    String strInput = inputName.getText().toString();
                    contactList.add(strInput);

                    addContact.setVisibility(View.VISIBLE);
                    inputName.getText().clear();
                    inputName.setVisibility(View.GONE);

                }
                return false;
            }
        });
    }

    private void initListData() {
        // temp data
        contactList.add("Jacob");
        contactList.add("Nicolas");
        contactList.add("David");
        contactList.add("Jacob");
        contactList.add("Nicolas");
        contactList.add("David");

    }
}

Then the code for my CustomAdapter is

public class MainListAdapter extends BaseAdapter {

    private static final String TAG = "MainListAdapter";

    private Context mContext;

    private LayoutInflater layoutInflater;

    private MyViewPager itemViewPager;

    private View viewMain;

    private View viewSlide;

    private TextView cancel;

    private TextView delete;

    private ArrayList<View> views;

    private PagerAdapter pagerAdapter;

    private List<String> mList;

    public MainListAdapter(Context context, List<String> list) {
        mContext = context;

        layoutInflater = LayoutInflater.from(mContext);
        mList = list;
    }

    @Override
    public int getCount() {
        return mList != null ? mList.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        return mList != null ? mList.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.listview_item, null);
        }

        viewMain = layoutInflater.inflate(R.layout.listview_item_main, null);
        viewSlide = layoutInflater.inflate(R.layout.listview_item_slide, null);

        cancel = (TextView)viewSlide.findViewById(R.id.tv_menu_cancel);
        delete = (TextView)viewSlide.findViewById(R.id.tv_menu_delete);
        cancel.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.v(TAG, "on click cancel");
                MyViewPager currPagerView = (MyViewPager)v.getParent().getParent();

                currPagerView.setCurrentItem(0, true);
                notifyDataSetChanged();
            }
        });
        delete.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.v(TAG, "on click cancel");
                itemViewPager.setCurrentItem(0, true);
                notifyDataSetChanged();
                MyViewPager currPagerView = (MyViewPager)v.getParent().getParent();

                deleteContact(currPagerView.getSelfIndex());
            }
        });

        views = new ArrayList<View>();
        views.add(viewMain);
        views.add(viewSlide);

        itemViewPager = (MyViewPager)convertView.findViewById(R.id.vp_list_item);
        itemViewPager.setSelfIndex(position);
        pagerAdapter = new PagerAdapter() {

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                ((MyViewPager)container).removeView(views.get(position));
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                ((MyViewPager)container).addView(views.get(position));
                // Log.v("PagerAdapter", "curr item positon is" + position);
                return views.get(position);
            }

            @Override
            public boolean isViewFromObject(View arg0, Object arg1) {
                return arg0 == arg1;
            }

            @Override
            public int getCount() {
                return views.size();
            }
        };

        fillItemData(convertView, position, viewMain);
        itemViewPager.setAdapter(pagerAdapter);
        itemViewPager.setCurrentItem(0);
        itemViewPager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                Log.v(TAG, "onPageSelected");

            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                Log.v(TAG, "onPageScrolled, " + "arg0=" + arg0 + ", arg1=" + arg1 + ", arg2="
                        + arg2);

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                Log.v(TAG, "onPageScrollStateChanged");

            }
        });

        // notifyDataSetChanged();
        // pagerAdapter.notifyDataSetChanged();
        return convertView;
    }

    private void fillItemData(View convertView, int position, View viewMain) {
        int[] colorCollection = {
                R.color.green, R.color.royalblue, R.color.violet
        };

        for (int i = 0; i < colorCollection.length; i++) {
            colorCollection[i] = mContext.getResources().getColor(colorCollection[i]);
        }

        int currColor = colorCollection[position % colorCollection.length];
        convertView.setBackgroundColor(currColor);

        TextView itemName = (TextView)viewMain.findViewById(R.id.tv_item_name);

        itemName.setText(mList.get(position));
        // Log.v(TAG, "item name is " + itemName.getText());
    }

    private void deleteContact(int postion) {
        mList.remove(postion);
    }
}

Then finally the ViewPagerAdapter code is

public class MyViewPager extends ViewPager {

    private static final String TAG = "MyViewPager";

    private float xDown;

    private float xMove;

    private float yDown;

    private float yMove;

    private boolean isScroll = false;

    private int selfIndex;

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

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

    public void setSelfIndex(int index) {
        selfIndex = index;
    }

    public int getSelfIndex() {
        return selfIndex;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        Log.v(TAG, "on intercept");
        if (event.getAction() == MotionEvent.ACTION_UP) {

        }
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.v(TAG, "on dispatch");
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            xDown = ev.getRawX();
            yDown = ev.getRawY();
            Log.v(TAG, "action down: " + xDown + ", " + yDown);
        } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            xMove = ev.getRawX();
            yMove = ev.getRawY();
            Log.v(TAG, "action move: " + xMove + ", " + yMove);
            if (isScroll) {
                getParent().requestDisallowInterceptTouchEvent(true);
                return super.dispatchTouchEvent(ev);
            }

            if (Math.abs(yMove - yDown) < 5 && Math.abs(xMove - xDown) > 20) {
                isScroll = true;
            } else {
                return false;
            }

        } else if (ev.getAction() == MotionEvent.ACTION_UP) {
            isScroll = false;
        }

        return super.dispatchTouchEvent(ev);
    }

}

The MainActivity layout is

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/background"
    tools:context="${packageName}.${activityClass}" >

    <ListView
        android:id="@+id/lv_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:listSelector="@android:color/transparent" />

</RelativeLayout>

The layout for listview_item is

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:minHeight="100dp" >

    <com.example.yo.view.MyViewPager
        android:id="@+id/vp_list_item"
        android:layout_width="fill_parent"
        android:layout_height="100dp" />

</RelativeLayout>

Added all XML Layouts

listview_item_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:minHeight="100dp" >

    <TextView
        android:id="@+id/tv_item_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/main_list_text"
        android:textSize="48sp"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/et_input_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/add_contact_hint"
        android:textColorHint="@color/main_list_text"
        android:textColor="@color/main_list_text"
        android:textSize="30sp"
        android:textStyle="bold"
        android:inputType="textCapCharacters"
        android:background="@null"
        android:textCursorDrawable="@null"
        android:singleLine="true"
        android:imeOptions="actionDone"
        android:visibility="gone" />

</RelativeLayout>

listview_item_slide

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:minHeight="100dp"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tv_menu_cancel"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:focusableInTouchMode="true"
        android:background="@color/gold"
        android:gravity="center"
        android:text="@string/cancel"
        android:textColor="@color/main_list_text"
        android:textSize="28sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_menu_delete"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="@color/green"
        android:gravity="center"
        android:text="@string/delete"
        android:textColor="@color/main_list_text"
        android:textSize="28sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_menu_block"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="@color/royalblue"
        android:gravity="center"
        android:text="@string/block"
        android:textColor="@color/main_list_text"
        android:textSize="28sp"
        android:textStyle="bold" />

</LinearLayout>

Please help me to listen to the onItemClickListener in the MainActivity's list. I am not able to figure out where I went wrong. Thanks in advance.

您必须将“setOnItemClickListener”放入MainActivity的Adapter类中。

public View getView(final int position, View convertView, ViewGroup parent) {
    // Declare Variables
    ViewHolder holder;
    View iView = convertView;


    if (convertView == null) {
        iView = inflater.inflate(R.layout.listview_item, parent, false);
        holder = new ViewHolder();

        holder.txt_name = (TextView) iView.findViewById(R.id.name);
        Typeface custom_fontG = Typeface.createFromAsset(
                context.getAssets(), "KozGoPr6N-Regular.otf");
        holder.txt_name.setTypeface(custom_fontG);

        holder.txt_desc = (TextView) iView.findViewById(R.id.detail);
        holder.ivProfile = (ImageView) iView.findViewById(R.id.flag);
        iView.setTag(holder);
    } else {
        holder = (ViewHolder) iView.getTag();
    }
    // Get the position
    resultp = data.get(position);

    // Locate the TextViews in listview_item.xml

    // Capture position and set results to the TextViews
    holder.txt_name.setText(resultp.get(OurTeam.TAG_NAME));
    holder.txt_desc.setText(resultp.get(OurTeam.TAG_DETAIL));


    imageLoader.displayImage(TAG_IMAGEURL + resultp.get((OurTeam.TAG_IMG)),
            holder.ivProfile, options);
    // Capture ListView item click
    iView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // Get the position
            // your code

        }
    });
    return iView;
}

At a time you can handle click event either in Adapter class of in Activity. in your case you are doing both.

And to manage

 addContact.setVisibility(View.GONE);
 inputName.setVisibility(View.VISIBLE);

Write above on click event of what ever is main view in listview_item layout (Do not forget to pass addContact and inputName views to your CustomAdapter).

public class MainActivity extends Activity {
private static final String TAG = "MainActivity";

private Context mContext;

private ListView mainListView;

private TextView addContact;

private EditText inputName;

private List<String> contactList = new ArrayList<String>();

private MainListAdapter mainAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);

    mContext = this;

    init();
}

private void init() {
    mainListView = (ListView)findViewById(R.id.lv_main);

    initListData();

    View footerView = getLayoutInflater().inflate(R.layout.listview_item_main, null);
    footerView.setBackgroundColor(getResources().getColor(R.color.gold));

    addContact = (TextView)footerView.findViewById(R.id.tv_item_name);
    addContact.setText(getString(R.string.plus));
    mainListView.addFooterView(footerView);

    mainAdapter = new MainListAdapter(mContext, contactList);
    mainListView.setAdapter(mainAdapter);

   /* mainListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
             Log.e(TAG, "on click item " + position);
            if (position == contactList.size()) {
                addContact.setVisibility(View.GONE);
                inputName.setVisibility(View.VISIBLE);
            }
        }
    });*/

    inputName = (EditText)footerView.findViewById(R.id.et_input_name);
    inputName.setOnEditorActionListener(new OnEditorActionListener() {

        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_GO) {
                InputMethodManager imm = (InputMethodManager)mContext
                        .getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm.isActive()) {
                    imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
                }
                String strInput = inputName.getText().toString();
                contactList.add(strInput);

                addContact.setVisibility(View.VISIBLE);
                inputName.getText().clear();
                inputName.setVisibility(View.GONE);

            }
            return false;
        }
    });
}

private void initListData() {
    // temp data
    contactList.add("Jacob");
    contactList.add("Nicolas");
    contactList.add("David");
    contactList.add("Jacob");
    contactList.add("Nicolas");
    contactList.add("David");

}

}

and Adapter Class was..

public class MainListAdapter extends BaseAdapter {

private static final String TAG = "MainListAdapter";

private Context mContext;

private LayoutInflater layoutInflater;

private MyViewPager itemViewPager;

private View viewMain;

private View viewSlide;

private TextView cancel;

private TextView delete;

private ArrayList<View> views;

private PagerAdapter pagerAdapter;

private List<String> mList;

public MainListAdapter(Context context, List<String> list) {
    mContext = context;

    layoutInflater = LayoutInflater.from(mContext);
    mList = list;
}

@Override
public int getCount() {
    return mList != null ? mList.size() : 0;
}

@Override
public Object getItem(int position) {
    return mList != null ? mList.get(position) : null;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = layoutInflater.inflate(R.layout.listview_item, null);
    }

    viewMain = layoutInflater.inflate(R.layout.listview_item_main, null);
    viewSlide = layoutInflater.inflate(R.layout.listview_item_slide, null);

    cancel = (TextView)viewSlide.findViewById(R.id.tv_menu_cancel);
    delete = (TextView)viewSlide.findViewById(R.id.tv_menu_delete);
    cancel.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Log.v(TAG, "on click cancel");
            MyViewPager currPagerView = (MyViewPager)v.getParent().getParent();

            currPagerView.setCurrentItem(0, true);
            notifyDataSetChanged();
        }
    });
    delete.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Log.v(TAG, "on click cancel");
            itemViewPager.setCurrentItem(0, true);
            notifyDataSetChanged();
            MyViewPager currPagerView = (MyViewPager)v.getParent().getParent();

            deleteContact(currPagerView.getSelfIndex());
        }
    });

    views = new ArrayList<View>();
    views.add(viewMain);
    views.add(viewSlide);

    itemViewPager = (MyViewPager)convertView.findViewById(R.id.vp_list_item);
    itemViewPager.setSelfIndex(position);
    pagerAdapter = new PagerAdapter() {

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ((MyViewPager)container).removeView(views.get(position));
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ((MyViewPager)container).addView(views.get(position));
            // Log.v("PagerAdapter", "curr item positon is" + position);
            return views.get(position);
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public int getCount() {
            return views.size();
        }
    };

    fillItemData(convertView, position, viewMain);
    itemViewPager.setAdapter(pagerAdapter);
    itemViewPager.setCurrentItem(0);
    itemViewPager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) {
            Log.v(TAG, "onPageSelected");

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            Log.v(TAG, "onPageScrolled, " + "arg0=" + arg0 + ", arg1=" + arg1 + ", arg2="
                    + arg2);

        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            Log.v(TAG, "onPageScrollStateChanged");

        }
    });

    // notifyDataSetChanged();
    // pagerAdapter.notifyDataSetChanged();

     convertView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            // your code here for list item click listener... 
        }
    })

    return convertView;
}

private void fillItemData(View convertView, int position, View viewMain) {
    int[] colorCollection = {
            R.color.green, R.color.royalblue, R.color.violet
    };

    for (int i = 0; i < colorCollection.length; i++) {
        colorCollection[i] = mContext.getResources().getColor(colorCollection[i]);
    }

    int currColor = colorCollection[position % colorCollection.length];
    convertView.setBackgroundColor(currColor);

    TextView itemName = (TextView)viewMain.findViewById(R.id.tv_item_name);

    itemName.setText(mList.get(position));
    // Log.v(TAG, "item name is " + itemName.getText());
}

private void deleteContact(int postion) {
    mList.remove(postion);
}

}

Add this to the parent of your Listview and parent of your listview_item and try again:

android:descendantFocusability="blocksDescendants"

Like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:descendantFocusability="blocksDescendants"
android:layout_height="match_parent"
android:background="@color/background"
tools:context="${packageName}.${activityClass}" >

<ListView
    android:id="@+id/lv_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:cacheColorHint="@android:color/transparent"
    android:listSelector="@android:color/transparent" />

and this:

  <?xml version="1.0" encoding="utf-8"?>
   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:descendantFocusability="blocksDescendants"
  android:minHeight="100dp" >
    <com.example.yo.view.MyViewPager
       android:id="@+id/vp_list_item"
       android:layout_width="fill_parent"
       android:layout_height="100dp" />

</RelativeLayout>

If this does not work, call isFocusable() on your EditText and TextView

addContact.isFocusable(false);

inputName.isFocusable(false);

I am guessing you made a common error. Please check/try both changes.

1) add android:descendantFocusability="blocksDescendants" into the ListView UI ("@+id/lv_main"). Note: If this and 2nd suggestion does not work, then the Listview layout may need rework.

2) mainListView.setItemsCanFocus(false);

Note: The Listview may be confused with focusing on an item in the UI.

I think the suggested code by "Nirmal Shethwala" looks good. It has the if/else block for if (convertView == null) .

EDIT : I noticed you inflated 3 xml layout files in getView() . You can only have one, and that is listview_item in your code. I know this is not well documented. I have tried this in the past. The reason is getView() method has to return only one view, and your code return convertView; like me. Sorry I know this will take some modifications in your layout.

add this below line in your listview_item parent layout only.

  android:descendantFocusability="blocksDescendants"

actually when the list item contains a element which can get focus then list item click listener not work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM