2011-11-28 19 views
22

Tôi hiện đang làm việc trên một dự án mà tôi cần một cái gì đó như sau:Multi-lớp ExpandableListView

- MainGroup 1 (Expandable) 
    - SubGroup 1 (Expandable) 
    - SubSubGroup 1 (Expandable) 
     - Child View 
     - Child View 
     - ... 
    - SubSubGroup 2 (Expandable) 
     - Child View 
     - Child View 
     - ... 
    - SubGroup 2 (Expandable) 
    - SubSubGroup 3 (Expandable) 
     - Child View 
     - ... 
    - SubSubGroup 4 (Expandable) 
     - Child View 
     - ... 
    - SubGroup 3 (Expandable) 
    - Child View 
    - ... 
- MainGroup 2 (Expandable) 
    - ... 

Tại hầu hết nó sẽ là một ExpandableListView bên trong một ExpandableListView bên trong một ExpandableListView - vì vậy 3 lớp ExpandableListView :

  • MainGroup sẽ chỉ giữ ExpandableListView khác.
  • SubGroup sẽ giữ các số khác ExpandableListView trừ hai số cuối cùng, allways sẽ chỉ là ChildViews. (Tôi nghĩ rằng hai chỉ có thể được thay thế bằng một cho SubSubGroup)
  • SubSubGroup allways giữ ChildViews.

Vấn đề của tôi là tôi nghĩ rằng tôi không hiểu các nguyên tắc cơ bản về cách bố trí ExpandableListView là trẻ em. Tôi đã xem xét các ví dụ như this, nhưng không thể xem xét chức năng của tôi.

Tôi đã thử chỉ cần thêm một số ExpandableListView làm trẻ em khác - nhưng một số thứ không hoạt động vì chỉ có mục đầu tiên bên trong ExpandableListView hiển thị nếu bạn mở rộng một trong các nhóm bên ngoài. Tuy nhiên tôi có thể bằng cách thiết lập chiều cao của các thùng chứa nhóm bên ngoài bằng tay làm cho nó đủ lớn để hiển thị tất cả các mục ở bên trong ExpandableListView. Để tối ưu, tính toán chiều cao nên tất nhiên được thực hiện khi đang bay.

Vì vậy, để có được một số câu hỏi vững chắc hơn:

  • Ai đó có thể cho tôi một lời giải thích của "vòng đời" ExpandableListView (bằng cách này tôi có nghĩa instantation, tái sử dụng các quan điểm, mở rộng/thính giả sụp đổ) bao gồm:
    • Làm thế nào và khi nào thì một số ExpandableListView được thông báo rằng một đứa trẻ được mở rộng/thu gọn?
    • Làm thế nào để ExpandableListView biết bao nhiêu không gian để làm cho tất cả trẻ em để phù hợp với một container nhóm?
  • Bao nhiêu lợi ích là có trong việc sử dụng ExpandableListView để tạo ra ở trên, so với chỉ trộn cùng giải pháp của riêng tôi sử dụng một số LinearLayouts và một số OnClickListeners?

Sửa

Đối với câu hỏi cuối cùng của tôi, tôi có thể lưu ý rằng có thể có bất cứ nơi nào từ 1 đến 20+ MainGroups.

+0

giải pháp của bạn đã được giải quyết ..? –

+0

Tôi chưa bao giờ thực sự giải quyết vấn đề khi tôi được chuyển sang một dự án khác, nhưng câu trả lời của QuickNick chắc chắn sẽ là cách để đi. – kaspermoerch

Trả lời

10

Trước hết, hãy để tôi khuyên bạn nên GrepCode trang web. Nó có nguồn của các lớp Android SDK. Cảm ơn họ, tôi đã tìm ra nguyên tắc cơ sở của AdapterViews (Tôi đã cung cấp cho bạn một liên kết đến ExpandableListView, nhưng tốt hơn nếu bạn nghiên cứu không chỉ nó, mà cả các phụ huynh lớp của nó nữa).

Bây giờ, câu hỏi của bạn và câu trả lời của tôi:

Làm thế nào và khi nào là một ExpandableListView thông báo rằng một đứa trẻ đang mở rộng/sụp đổ?

Xem phương pháp handleItemClick(View v, int position, long id)

như thế nào ExpandableListView biết bao nhiêu không gian để làm cho tất cả trẻ em để phù hợp với một container nhóm?

Tôi đã không nghiên cứu câu hỏi này tốt, nhưng theo như tôi biết, nó được tạo bởi phương thức requestLayout(). Ngoài ra, chúng tôi phát hiện ra rằng một Chế độ xem có thể cuộn không thể được nhúng vào Chế độ xem có thể cuộn khác. (Đó là sai lầm phổ biến: đặt ListView vào ScrollView hoặc ListView vào ExpandableListView).

Bao nhiêu lợi ích là có trong việc sử dụng ExpandableListView để tạo trên, so với chỉ trộn cùng giải pháp của riêng tôi sử dụng một số LinearLayouts và một số OnClickListeners?

AdapterXem nhanh hơn. Nhưng quá trình xây dựng của bạn quá phức tạp ngay cả với ExpandableListView. Bạn có thể sử dụng 2 giải pháp.

  1. Guru-giải pháp: nếu bạn là chuyên nghiệp thiết kế của riêng bạn Views/ViewGroups từ đầu (Ý tôi là, bạn hiểu phương pháp requestLayout(), dispatchDraw() và vân vân), sau đó viết riêng của bạn GrandExpandableListAdapter có 3 cấp độ.
  2. Giải pháp trung bình: sử dụng expandableListAdapter cho 2 cấp đầu tiên và sử dụng LinearLayouts cho cấp 3.
1

Bạn có thể muốn kiểm tra dự án this. Tôi đã không thử nó, nhưng tôi đoán nó có giá trị một thử. ExpanadableListView mặc định là khá hạn chế, được thiết kế ban đầu để chỉ hỗ trợ 2 cấp độ. Bạn có thể hack xung quanh với nó để có được nó để hỗ trợ nhiều cấp độ hơn thế, nhưng nó sẽ nhận được lộn xộn.

+0

Việc sử dụng nó sẽ ảnh hưởng đến việc cấp phép của tôi như thế nào? Tôi đang phát triển cho một công ty, vì vậy tôi không thể thực sự làm những thứ có thể yêu cầu mã nguồn của tôi trở thành nguồn mở. – kaspermoerch

+0

Tôi không cho rằng giấy phép BSD yêu cầu bạn giữ cho dự án của bạn mở nguồn. Ít nhất tôi không thể tìm thấy bất cứ điều gì mà tiểu bang khác ở đây: http://www.opensource.org/licenses/bsd-license.php. Mặc dù vậy tôi có thể sai lầm khủng khiếp. –

+0

Cấp phép sang một bên - nó sẽ hoàn thành mục đích của tôi để +1. Tôi thấy rằng chỉ cần chạy các ví dụ đơn giản được cung cấp trong nguồn là khá laggy, vì vậy tôi vẫn đang tìm câu trả lời cho câu hỏi của tôi. – kaspermoerch

1

Mặc dù đây không phải là giải pháp hoàn chỉnh mà vẫn là Danh sách có thể mở rộng 3 lớp. Vì vậy, nó để lại cho bạn cách bạn phong cách nó.

đây là lớp

package com.custom.nagee; 

import android.app.ExpandableListActivity; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseExpandableListAdapter; 
import android.widget.ExpandableListView; 
import android.widget.LinearLayout; 

public class CustomemExpandible extends ExpandableListActivity{ 
    LayoutInflater inflator; 
    boolean flag = true; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     inflator = LayoutInflater.from(getApplicationContext()); 
     setListAdapter(new MyAdapter()); 
    } 

    @Override 
    public boolean onChildClick(ExpandableListView parent, View v, 
      int groupPosition, int childPosition, long id) { 
     if(flag){ 
      v.findViewById(childPosition).setVisibility(View.VISIBLE); 
      flag = false; 
      return true; 
     } 
     v.findViewById(childPosition).setVisibility(View.GONE); 
     flag = true; 
     return true; 
    } 
    class MyAdapter extends BaseExpandableListAdapter{ 

     @Override 
     public Object getChild(int groupPosition, int childPosition) { 
      return null; 
     } 

     @Override 
     public long getChildId(int groupPosition, int childPosition) { 
      return 0; 
     } 

     @Override 
     public View getChildView(int groupPosition, int childPosition, 
       boolean isLastChild, View convertView, ViewGroup parent) { 
      LinearLayout linearLayout = (LinearLayout)inflator.inflate(R.layout.group, null); 
      linearLayout.getChildAt(1).setId(childPosition); 
      return linearLayout; 
     } 

     @Override 
     public int getChildrenCount(int groupPosition) { 
      return 2; 
     } 

     @Override 
     public Object getGroup(int groupPosition) { 
      return null; 
     } 

     @Override 
     public int getGroupCount() { 
      return 2; 
     } 

     @Override 
     public long getGroupId(int groupPosition) { 
      return 0; 
     } 

     @Override 
     public View getGroupView(int groupPosition, boolean isExpanded, 
       View convertView, ViewGroup parent) { 
      return ((LinearLayout)inflator.inflate(R.layout.group, null)); 
     } 

     @Override 
     public boolean hasStableIds() { 
      // TODO Auto-generated method stub 
      return false; 
     } 

     @Override 
     public boolean isChildSelectable(int groupPosition, int childPosition) { 
      return true; 
     } 

    } 
} 

và ở đây đi các tập tin xml

group.xml

<?xml version="1.0" encoding="utf-8"?> 

<TextView 
    android:id="@+id/editText1" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textColor="@color/back" 
    android:layout_marginLeft="30dip" 
    android:text="DONE" > 
</TextView> 

<LinearLayout 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:layout_marginLeft="30dip" 
    android:visibility="gone" > 

    <TextView 
     android:id="@+id/editText2" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="DONE"> 
    </TextView> 

    <TextView 
     android:id="@+id/editText3" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="DONE" /> 

    <TextView 
     android:id="@+id/editText4" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="DONE" /> 
</LinearLayout> 

và đây là thư mục màu để thay đổi màu văn bản, bên trái của bạn, bạn thậm chí có thể thay đổi nền để có giao diện đẹp hơn.

back.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_enabled="false" android:color="#808080"/> 
    <item android:state_window_focused="false" android:color="#808080"/> 
    <item android:state_pressed="true" android:color="#808080"/> 
    <item android:state_selected="true" android:color="#000000"/> 
    <item android:color="#FF0000"/> <!-- not selected --> 
</selector> 

hy vọng nó hoạt động ...