loại của Menu
Hãy để tôi bắt đầu bằng việc phác thảo sự phân biệt giữa Contextual Menus và Popup Menus (lấy từ here):Triggering một PopupMenu với các nút bên trong một mục ListView
Một PopupMenu là một phương thức menu được neo vào Chế độ xem
Trình đơn ngữ cảnh [Tôi đang nói cụ thể về menu ngữ cảnh nổi] cung cấp các tác vụ ảnh hưởng đến một mục cụ thể hoặc khung xt trong giao diện người dùng. Bạn có thể cung cấp menu ngữ cảnh cho bất kỳ chế độ xem nào nhưng chúng thường được sử dụng cho các mục trong một bộ sưu tập ListView, GridView hoặc chế độ xem khác, trong đó người dùng có thể thực hiện các tác vụ trực tiếp trên mỗi mục.
Như hướng dẫn, các tài liệu phân biệt giữa sử dụng của họ: - PopupMenu: "Cung cấp một thực đơn tràn kiểu cho hành động mà liên quan đến nội dung cụ thể (chẳng hạn như tiêu đề email của Gmail ..." - ContextualMenu : "Đối với hành động mà ảnh hưởng nội dung được lựa chọn ..."
tôi là sau khi giao diện trực quan và tương tác của các PopupMenu
M. y setup (và goal)
Tôi có một ListView trong đó mỗi mục có một nút ở bên phải.
--------------------
| Item 1 [ ]|
--------------------
--------------------
| Item ... [ ]|
--------------------
--------------------
| Item n [ ]|
--------------------
trong khi giữ lại onItemClick
cho mỗi ListItem, tôi muốn tận dụng nút để kích hoạt một PopupMenu
.
Các hành động trong PopupMenu
được liệt kê trong my_menu.xml
, do đó, sự khác biệt duy nhất giữa mỗi trường hợp của menu là mục mà nó được nhấp vào.
Những gì tôi đã cố gắng
Tôi đã thử trọng getView()
trong ListAdapter
tôi thêm một OnClickListener
cho mỗi nút, theo this post. Kết quả không nhất quán; không phải tất cả các nhấp chuột đều được đăng ký (có lẽ do tái chế - tôi chưa có tried this fix) nhưng nói chung cách tiếp cận có vẻ hơi khó khăn, xem xét việc dễ dàng chỉ định một menu ngữ cảnh cho một listview.
Tôi cũng đã thử thêm một menu ngữ cảnh, đã chết dễ dàng, ngoại trừ việc nó chỉ được kích hoạt khi mục danh sách được nhấn lâu.
Phương pháp getView()
có phải là cách để đi hoặc có điều gì đó dễ dàng hơn không?
Trong chế độ xem danh sách của tôi, tôi có nút tràn nhỏ cho mỗi mục, tương tự như mỗi bản nhạc trong danh sách phát cho Play Âm nhạc. Họ hiển thị PopupMenu cho mỗi mục ở đó, khi bạn nhấp vào nút tràn. Nhấn và giữ không có gì.
Tôi thích điều đó nhưng không chắc chắn như thế nào? Trang menu chỉ trình bày cách bật menu bật lên cho các chế độ xem riêng lẻ.
registerForContextMenu(ListView lv)
là điều duy nhất tôi thấy rằng tôi có thể áp dụng cho toàn bộ ListView, nhưng điều đó dường như chỉ hoạt động trên các lần nhấn dài toàn bộ danh sách. Có cách nào để móc sự kiện đó vào một lần nhấp vào một chế độ xem cụ thể trong một mục danh sách (trong khi vẫn duy trì mục danh sách nhấp cho phần còn lại của mục danh sách) không?
Tôi đã thử đặt onClickListener
trong getView()
như được mô tả ở đây nhưng nó cảm thấy ngột ngạt cho PopupMenu và không phải tất cả các lần nhấp đều được đăng ký mọi lúc (nó không nhất quán).
Update - với getView() ghi đè một lần nữa
Khi tôi tạo ra StacksCursorAdapter, tôi vượt qua một thể hiện của StackViewFragment mà được lưu giữ như một lĩnh vực (vì vậy nó có thể được giao cho quan điểm như người nghe nhấp chuột).
ViewHolder
là một lớp học với public final ImageView miniOverflow
StacksCursorAdapter (mở rộng SimpleCursorAdapter):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder) row.getTag();
if (holder == null) {
holder = new ViewHolder(row);
row.setTag(holder);
}
holder.miniOverflow.setTag(R.id.tag_stack_position, position);
holder.miniOverflow.setOnClickListener(listener);
return row;
}
StackViewFragment (mở rộng ListFragment, thực hiện View.OnClickListener):
@Override
public void onClick(View v) {
Log.d(TAG, "mini overflow clicked");
Log.d(TAG, "position:::::" + v.getTag(R.id.tag_stack_position));
PopupMenu popup = new PopupMenu(getActivity(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_stackview_listitem, popup.getMenu());
popup.show();
}
stack_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- a single row item for a Stacks listview -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:descendantFocusability="blocksDescendants"
>
...
<other views>
...
<ImageView
android:id="@+id/moreoverflow_btn"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:alpha="0.4"
android:scaleType="fitCenter"
android:src="@drawable/ic_menu_moreoverflow_black"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
Sự cố tại ngã ba này là thỉnh thoảng tôi phải nhấp nhiều lần để nhận được nhấp chuột để đăng ký (trên nút). Điều này là không có cuộn, vì vậy nó không liên quan đến xem tái chế.
Kết (giải pháp bởi eskimoapps.com đánh dấu là đúng)
Vì vậy, không có vấn đề với nhiều lần nhấp chuột ngoại trừ mục tiêu liên lạc của tôi đã không ở nơi tôi đã mong đợi - tài sản hình ảnh tôi đã được sử dụng cho tràn nhỏ được đặt ở bên phải (sao cho ba dấu chấm gần cạnh phải của mục tiêu cảm ứng) có nghĩa là tôi chỉ bị thiếu một nửa thời gian (facepalm).
Overriding getView()
như tôi đã giới thiệu ở trên dường như làm việc tốt, và trên thực tế, getView()
thể được sửa đổi hơn nữa, bằng cách thiết lập OnClickListener chỉ khi nó là cần thiết (nhưng chắc chắn, cập nhật thẻ cần phải được thực hiện cho mỗi xem , không chỉ những người mới được tạo):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder) row.getTag();
if (holder == null) {
holder = new ViewHolder(row);
row.setTag(holder);
holder.miniOverflow.setOnClickListener(listener);
}
holder.miniOverflow.setTag(R.id.tag_stack_position, position);
return row;
}
u có thể xin vui lòng mô tả cách u thêm người biết lắng nghe? đối tượng nghe là gì? holder.miniOverflow.setOnClickListener (người nghe); –
@mahdi nó sẽ thuộc loại 'View.OnClickListener' – ataulm