Android ListView コンポーネントに非常に奇妙な問題があります。
状況: 私は基本的に setOnItemClickListener メソッドを利用しており、その後 "onItemClick" メソッドをオーバーライドして、リストビュー内の項目をクリックしたときにカスタム アクションを実装しています。
問題: アイテムのタップ時に onItemClick イベントが発生するはずですが、かなりの量 (20-30-40) のアイテムをタップすると、突然 1 つのアイテムだけがタップできなくなります。つまり、タップしても何も起こりません。タップします。その間、他のすべてのアイテムは引き続きタップ可能です。
「dispatchTouchEvent」をキャプチャするために ListView コンポーネントをオーバーライドしました (以下のコードを参照)。これにより、項目が突然タップできなくなった場合でも、適切な X 座標と Y 座標を使用して、dispatchTouchEvent が実際に引き続き起動されることがわかりますが、どういうわけか「onItemClick " イベントが発生しません。
public class ExtendedListView extends ListView
{
public ExtendedListView(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
Log.v("dispatchTouchEvent", "click|X:" + ev.getX() + "|Y:" + ev.getY());
return super.dispatchTouchEvent(ev);
}
}
ListView を開始するメソッド:
@SuppressWarnings("unchecked")
private void renderHomeScreenItemsList() {
HomeScreenItemAdapter m_adapter;
ArrayList<HomeScreenItem> lHomeScreenItems = null;
LayoutParams lpHomeScreenItems = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
lpHomeScreenItems.leftMargin = Util.dipsToPx(0, this);
lpHomeScreenItems.topMargin = Util.dipsToPx(155, this);
lpHomeScreenItems.gravity = 3; //3 = LEFT. Some gravity is necessary.
lvHomeScreenItems = new ExtendedListView(this);
lvHomeScreenItems.setLayoutParams(lpHomeScreenItems);
ColorDrawable sage = new ColorDrawable(this.getResources().getColor(R.color.HomeScreenDividerColor));
lvHomeScreenItems.setDivider(sage);
lvHomeScreenItems.setDividerHeight(1);
lvHomeScreenItems.setCacheColorHint(Color.WHITE);
lvHomeScreenItems.setBackgroundColor(Color.WHITE);
lHomeScreenItems = new ArrayList<HomeScreenItem>();
Iterator<EnabledSection> ite = Global.EnabledSectionsVector.iterator();
while (ite.hasNext()) {
EnabledSection es = (EnabledSection) ite.next();
HomeScreenItem h1 = new HomeScreenItem();
h1.setItemText(es.FunctionTitle);
h1.setFunctionName(es.FunctionName);
int imageId = getResources().getIdentifier("homescreen_" + es.FunctionName.toLowerCase(), "drawable", "XXXXXXXXX");
h1.setItemImageResourceId(imageId);
lHomeScreenItems.add(h1);
}
HomeScreenItem hCopyright = new HomeScreenItem();
hCopyright.setItemText("copyright");
hCopyright.setItemImageResourceId(-1);
lHomeScreenItems.add(hCopyright);
m_adapter = new HomeScreenItemAdapter(this, R.layout.row, lHomeScreenItems);
lvHomeScreenItems.setAdapter(m_adapter);
lvHomeScreenItems.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.v("onItemClick", "Click Detected");
HomeScreenItem hmi = (HomeScreenItem)parent.getItemAtPosition(position);
Boolean blnAcceptClick = true;
if (WrapperWebView == null)
blnAcceptClick = true;
else
if (WrapperWebView.getProgress() != 100)
blnAcceptClick = false;
if (hmi.getItemImageResourceId() != -1 && blnAcceptClick)
{
Global.IsLoadingWrapper = true;
vSelectedItem = view;
ImageView ivIcon = (ImageView)view.findViewById(R.id.rightarrow);
LinearLayout ll = (LinearLayout)view.findViewById(R.id.RowContainer);
TextView ll2 = (TextView)view.findViewById(R.id.toptext);
ll.setBackgroundResource(R.color.BlueActive);
ll2.setBackgroundResource(R.color.BlueActive);
ll2.setTextColor(Color.WHITE);
int[] intCoordinates = new int[2];
view.getLocationInWindow(intCoordinates);
lpLoadingSpinner.topMargin = intCoordinates[1] - Util.dipsToPx(10, HomeScreen.this);
ivLoadingSpinner.setVisibility(View.VISIBLE);
ivLoadingSpinner.bringToFront();
LoadingSpinnerAnimation.start();
ivIcon.setVisibility(View.GONE);
ivClickedItemIcon = ivIcon;
InitializeWebView(hmi.getFunctionName());
}
}
});
}
どんな助けでも大歓迎です。このバグは、複数のデバイスと複数の Android バージョンで発生することが確認されています。
更新: 問題が修正され ました 問題を見つけて修正することができました。基本的に、アイテムのリストにはすべての「通常の」アイテム (私の文脈では) が含まれていましたが、一番下のアイテムは、クリック可能にする必要があるリンク (青色) を持つ「著作権」アイテムでした。このクリック効果を機能させるには、次を使用しました。
tt.setMovementMethod(LinkMovementMethod.getInstance());
レンダリングされているアイテムが著作権アイテムであった場合。
ただし、レンダリングされるアイテムが「通常の」アイテムである場合、その効果に対抗しなかったため、通常のアイテムがレンダリングされるときに以下の行を追加するだけで、問題は解消されました。
tt.setMovementMethod(null);
完全なサンプル コード (関係のないコードは削除されています)
public class HomeScreenItemAdapter extends ArrayAdapter<HomeScreenItem> {
private ArrayList<HomeScreenItem> items;
public HomeScreenItemAdapter(Context context, int textViewResourceId, ArrayList<HomeScreenItem> items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
HomeScreenItem o = items.get(position);
if (o != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
if (iv != null && tt != null)
{
if (position != (items.size() - 1))
{
tt.setMovementMethod(null);
}
else
{
//last element, so setup element to show copyright notice instead
tt.setMovementMethod(LinkMovementMethod.getInstance()); //this makes the link clickable
}
}
}
return v;
}
}