2012-06-19 24 views
90

Dưới đây là đoạn mã có ListView. Tôi đã thêm một emptyView và một headerView. Thêm headerView làm cho vị trí trong onItemClick được tăng lên một.ListView addHeaderView khiến vị trí tăng lên một lần?

Vì vậy, không có tiêu đềXem phần tử danh sách đầu tiên sẽ có vị trí 0, với tiêu đềXem vị trí của phần tử danh sách đầu tiên sẽ là 1!

Điều này gây ra lỗi trong bộ điều hợp của tôi, ví dụ: khi gọi getItem() và sử dụng một số phương thức khác, xem bên dưới. Điều lạ: Trong phương thức getView() của bộ điều hợp, phần tử danh sách đầu tiên được yêu cầu với vị trí 0 ngay cả khi headerView được thêm vào !!

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    ListView list = (ListView) viewSwitcher.findViewById(R.id.list); 
    View emptyView = viewSwitcher.findViewById(R.id.empty); 
    list.setEmptyView(emptyView); 

    View sectionHeading = inflater.inflate(R.layout.heading, list, false); 
    TextView sectionHeadingTextView = (TextView) sectionHeading.findViewById(R.id.headingText); 
    sectionHeadingTextView.setText(headerText); 
    list.addHeaderView(sectionHeading); 

    list.setAdapter(listAdapter); 

    list.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      listAdapter.getItem(position); 
      //Do something with it 
     } 
    }); 
} 

Một số phương pháp adapter:

@Override 
public int getViewTypeCount() { 
    return TYPE_COUNT; 
} 

@Override 
public int getItemViewType(int position) { 
    return (position < items.size()) ? ITEM_NORMAL : ITEM_ADVANCED; 
} 

    @Override 
public Product getItem(int position) { 
    return items.get(position); 
} 
@Override 
public boolean areAllItemsEnabled() { 
    return false; 
} 

@Override 
public boolean isEnabled(int position) { 
    return (position < items.size()); 
} 

Đây có phải là hành vi bình thường khi thêm một headerView ?? Và làm cách nào để khắc phục sự cố trong bộ điều hợp của tôi?

+1

Câu hỏi của bạn đã có câu trả lời cho câu hỏi của tôi. +1 –

Trả lời

108

Tôi vừa gặp vấn đề này và tốt nhất cách dường như sử dụng các tài khoản phiên bản ListView.getItemAtPosition(position) thay vì ListAdapter.getItem(position) như ListView cho các tiêu đề, ví dụ: -

làm điều này thay vì:

myListView.getItemAtPosition(position) 
+1

Đúng vậy! 'onItemClick' cung cấp cho bạn một' parent' vì một lý do. Bạn có thể sử dụng 'parent.getItemAtPosition (position)' –

+3

Điều này didnt thực sự làm việc cho tôi trong khi sử dụng @whuandroid trang trí/wrapper adapter giải pháp nào. – Dori

+2

bạn cũng phải bỏ mục trong trường hợp này. – njzk2

27

Nếu bạn thêm tiêu đề vào ListView sẽ trở thành mục đầu tiên trong danh sách. Bạn có thể bù đắp cho điều này bằng cách ghi đè số getCount() để trả lại một mục ít hơn, nhưng đảm bảo bạn xử lý getItem(), getItemId() và cứ như vậy tiêu đề sẽ là mục ở vị trí 0.

+6

Ghi đè getCount() để trả lại một mục ít hơn không hoạt động, bởi vì sau đó tôi bỏ lỡ mục danh sách cuối cùng của danh sách. Nếu chỉ có 1 mục trong danh sách thì getView() sẽ không bao giờ được gọi. Hơn nữa bộ điều hợp được tách ra khỏi danh sách xem và không biết liệu có một tiêu đề được thêm vào listview hay không. – d1rk

+2

Trong vị trí thiết lập ListItemClick = vị trí - 1 nếu có tiêu đề đính kèm, tôi nghĩ đó là những gì tôi đã làm khi tôi gặp vấn đề cụ thể này, nó không phải là rất gọn gàng, nhưng cách duy nhất tôi có thể nghĩ về – akshaydashrath

+3

Tôi đoán cách dễ nhất được đặt vị trí = vị trí- (số lượng headerviews bổ sung) trong OnItemClickListener như bạn đã đề xuất. Tôi đã thay đổi bộ điều hợp của mình để xử lý bản thân headerview, do đó tôi không phải gọi addHeaderView trên listview. Mặc dù bộ điều hợp có phức tạp hơn một chút. – d1rk

5

Một giải pháp này là để lập bản đồ id lập chỉ mục. Về cơ bản, id sẽ trả về chỉ mục trong danh sách và trình nghe nhấp chuột sẽ thực hiện:

public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      listAdapter.getItem((int) id); 
} 
8

Không sử dụng bộ điều hợp của bạn, sử dụng bộ điều hợp 'trang trí' từ getAdapter.

+0

+1 IMO này là cách để đi - bộ điều hợp mà bạn cung cấp được bao bọc với một bộ điều hợp khác đưa chỉ số này vào tài khoản khi bạn cung cấp tiêu đề. Mã này cho việc này là sử dụng này được đưa ra bởi @Ramesh ở nơi khác trên trang này (+1 cho bạn quá!) – Dori

+0

Điều này làm việc như một say mê, cảm ơn! – javaxian

13

Không cần thay đổi bất kỳ mã nào. Chỉ cần sử dụng mã bên dưới.

list.setOnItemClickListener(new OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     parent.getAdapter().getItem(position); 
     //Do something with it 
    } 
}); 
+1

Điều này thường sẽ cần phải đúc, vì mục được trả lại chỉ là "Đối tượng". –

32

Nếu bạn không quan tâm về nhấp chuột vào tiêu đề, trừ đi số lần xem tiêu đề từ vị trí để có được vị trí cho bộ chuyển đổi của bạn:

 listView.addHeaderView(inflater.inflate(
       R.layout.my_hdr_layout, null), null, false); 
     listView.setAdapter(m_adapter); 
     listView.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 
      position -= listView.getHeaderViewsCount(); 
      final MyObject object = m_adapter.getItem(position); 

     } 
    }); 
+0

Giải pháp rất hay làm việc cho tôi như một sự quyến rũ, cảm ơn !!! +1 cho bạn – Josef

+0

Đây là giải pháp phù hợp và tốt nhất – Shirane85

+0

Đây phải là câu trả lời hay nhất, tôi không quan tâm đến tiêu đề, tôi quan tâm đến danh sách. – Ninja

0

Không để thêm nhiều mới @Ramesh không thêm nhưng một số ngữ cảnh bổ sung:

personList.setOnItemClickListener(new OnItemClickListener() { 
    @SuppressWarnings("unchecked") 
    public void onItemClick(AdapterView<?> parent, View view, int position, long duration) { 
     Map<String, Object> person = (Map<String, Object>) parent.getAdapter().getItem(position); 
     if (person != null){ 

      // If the header was clicked on a null is returned 

      OnPersonUiChangeListener listener = (OnPersonUiChangeListener) getActivity(); 
      listener.onSelectedPersonChanged(person); 
     } 
    } 
}); 
14

Khi thực hiện AdapterView.OnItemClickListener chúng tôi chỉ trừ tiêu đề khỏi vị trí.

@Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
    position -= mListView.getHeaderViewsCount(); 
    // what ever else follows... 
} 
0

Sử dụng getSelectedItemPosition() Trả lại vị trí của mục hiện được chọn trong bộ dữ liệu của bộ điều hợp. Phương pháp này không cần phải lo lắng về kích thước của đầu trang hoặc chân trang.

2

Xin chào, chúng tôi có thể giải quyết vấn đề này theo cách này trước tiên bạn tạo chế độ xem tiêu đề, sau khi chèn vào danh sách của bạn và bước cuối cùng không thể setOnClickListener. công trình của nó cho tôi.bất kỳ thông tin phản hồi chào đón

ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false); 
list.addHeaderView(headerView); 
headerView.setEnabled(false); 
headerView.setOnClickListener(null); 
+0

Đó là cách xuống danh sách các câu trả lời, nhưng điều này thực sự hữu ích. Nếu bạn không thực hiện những thay đổi này, thì chế độ xem tiêu đề của bạn sẽ vẫn có thể nhấp, với hiệu ứng gợn, v.v. –

0

này có thể giúp ai đó, cải thiện trên Farid_z và Philipp của câu trả lời, chúng ta có thể áp dụng một cách chính xác các setItemChecked và setTitle với một cái gì đó như thế này

 FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit(); 
     position += 1; 
     mDrawerList.setItemChecked(position, true); 
     mDrawerList.setSelection(position); 
     position -= 1; 
     setTitle(mNavigationDrawerItemTitles[position]); 
     mDrawerLayout.closeDrawer(mDrawerList); 
Các vấn đề liên quan