getChildView不会被调用 [英] getChildView not being called

查看:1456
本文介绍了getChildView不会被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提出一个菜单,其中包括自定义ExpandableListView适配器。尽管试图在网上与我的code尽可能靠近API的例子,我见过的任何其他例子(包括多个密切相关的SO问题),我仍然无法得到它的工作。

I am making a menu which includes a custom ExpandableListView adapter. Despite trying to match my code as close to the API examples and any other examples I've seen online (including multiple closely related SO questions), I still can't get it working.

我知道该适配器被使用,因为该组查看正在显示(这是从一个XML制造)。点击该组项目还呼吁getGroupView,但code从不运行getChildView,getChild,或getChildId。

I know the adapter is being used because the group view is being shown (which is made from an xml). Clicking on the group item also calls "getGroupView", but the code never runs "getChildView", "getChild", or "getChildId".

我已经通过Android-15源$ C ​​$ C还跟找出我可能做错了,但没有什么奇怪的了上来。

I've even went through the Android-15 source code to find out what I might have done wrong, but nothing odd has came up.

=基本活动

public class SettingsM extends FragmentActivity
{
    static Context context;
    ViewPager mViewPager;
    CollectionPagerAdapter mDemoCollectionPagerAdapter;
    //ColorPicker picker;

    SharedPreferences preferences;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

        context = this;
        // Set up action bar.
        final ActionBar actionBar = getActionBar();

        actionBar.setDisplayHomeAsUpEnabled(false);
        actionBar.setDisplayUseLogoEnabled(false);
        actionBar.setTitle("Particle emitter settings");

        // get the preferences for this screen
        preferences = this.getSharedPreferences("base_world", 0);

        // tab holder
        setContentView(R.layout.tabmenu_holder);
        mViewPager = (ViewPager) findViewById(R.id.pager);

        mDemoCollectionPagerAdapter = new CollectionPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mDemoCollectionPagerAdapter);
    }

    public class CollectionPagerAdapter extends FragmentStatePagerAdapter
    {
        public CollectionPagerAdapter(FragmentManager fm) 
        {
            super(fm);
        }

        @Override
        public Fragment getItem(int i)
        {
            Fragment fragment = new TabFragment();
            Bundle args = new Bundle();
            if(preferences != null)
                {
                if(i == 0)
                {// world
                    args.putBoolean("world", true);
                } else
                {// emitter
                    args.putBoolean("world", false);
                    args.putInt("emitter", i-1);
                }
            }
            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public int getCount()
        {
            return 100;
        }

        @Override
        public CharSequence getPageTitle(int position) 
        {
            if(position == 0)
            {
                return "World";
            } else
            {
                return "Emitter #" + position;
            }
        }
    }

    public static class TabFragment extends Fragment
    {        
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        {
            Bundle args = getArguments();
            View rootView = new TextView(context);// use a textview as the default

            if(args.getBoolean("world"))
            {
                rootView = inflater.inflate(R.layout.m_backdrop, container, false);

                // add face drop-down
                ExpandableListView face_list = (ExpandableListView) rootView.findViewById(R.id.FaceList);
                if(face_list != null)
                {
                    face_list.setAdapter(new ExpandableFaceList(context));
                    face_list.setOnGroupClickListener(new OnGroupClickListener()
                    {

                        @Override
                        public boolean onGroupClick(ExpandableListView parent,
                            View v, int groupPosition, long id)
                        {
                            Log.i("FaceList", "Clicked:" + groupPosition);
                            return false;
                        }
                    });
                }

            } else
            {
                return rootView;
            }
            return rootView;
        }
    }
}

=扩展列表视图适配器

= Expandable List view Adapter

public class ExpandableFaceList extends BaseExpandableListAdapter implements ExpandableListAdapter
{
    public Context context;
    private LayoutInflater inflator;
    private float mDensity = 1f;

    private boolean bShowSw = true;
    private ColorPickerMenuView cp;
    private Switch sw;


    public ExpandableFaceList(Context context)
    {
        this.context = context;
        this.inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mDensity = context.getResources().getDisplayMetrics().density;
    }

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

    @Override
    public int getChildrenCount(int groupPosition)
    {
        return 6;// because there are 6 faces to a cube
    }

    // list views
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent)
    {
        View v = convertView;
        TextView tv;

        if(v == null)
        {
            v = inflator.inflate(R.layout.exlist_head, parent, false);

            tv = (TextView) v.findViewById(R.id.exList_Title);
            if(tv != null)
                tv.setText("Face Colors");

            tv = (TextView) v.findViewById(R.id.exList_Summary);
            String s_text = "The color for each face, click to ";
            s_text += ((isExpanded)? "collaspe": "expand");
            if(tv != null)
                tv.setText(s_text);
        } else
        {
            tv = (TextView) v.findViewById(R.id.exList_Summary);
            String s_text = "The color for each face, click to ";
            s_text += ((isExpanded)? "collaspe": "expand");
            if(tv != null)
                tv.setText(s_text);
            parent.invalidate();
        }        

        return v;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent)
    {
        View v = convertView;

        if(v == null)
        {
            if(bShowSw)
            {
                v = (LinearLayout) inflator.inflate(R.layout.face_info_sw, parent, false);
            } else
            {
                v = (LinearLayout) inflator.inflate(R.layout.face_info, parent, false);
            }
        }

        switch(childPosition)
        {
        case 0:
            v.setTag("Front");
            break;
        case 1:
            v.setTag("Back");
            break;
        case 2:
            v.setTag("Left");
            break;
        case 3:
            v.setTag("Right");
            break;
        case 4:
            v.setTag("Top");
            break;
        case 5:
            v.setTag("Bottom");
            break;
            }

        Log.i("ELV", "Pos:" + childPosition);

        cp = (ColorPickerMenuView) v.findViewById(R.id.face_color);
        cp.setTitle((String) v.getTag());

        cp.setOnClickListener(new OnClickListener() {
            public void onClick(View v) { UpdateData(v); }
        });

        if(bShowSw)
        {
            sw = (Switch) v.findViewById(R.id.face_sw);
            sw.setOnClickListener(new OnClickListener() {
                public void onClick(View v) { UpdateData(v); }
            });
        }

        return v;
    }

    private void UpdateData(View v) { }

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

    @Override
    public Object getChild(int groupPosition, int childPosition)
    {
        return "Child:" + groupPosition + "." + childPosition;
    }

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

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

    @Override
    public boolean hasStableIds()
    {
        return true;
    }

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

=活动的XML视图

= Activity's xml view

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.PagerTitleStrip android:id="@+id/pager_title_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33b5e5"
        android:textColor="#fff"
        android:paddingTop="4dp"
        android:paddingBottom="4dp" />

</android.support.v4.view.ViewPager>

= m_backdrop.xml(菜单背景设置)

= m_backdrop.xml (menu for the backdrop setting)

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:app="http://schemas.android.com/apk/res/com.zyphronics.aquafinger">

      <RelativeLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:orientation="vertical" >

            <TextView
            android:id="@+id/Title_GeneralSettings_text"
            style="?android:attr/listSeparatorTextViewStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dip"
            android:text="General Settings" />

        <ExpandableListView
            android:id="@+id/FaceList"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_below="@id/Title_GeneralSettings_text" >
        </ExpandableListView>

        </RelativeLayout>

</ScrollView>

= face_info.sw.xml(该face_info.xml是相同的,但没有开关)

= face_info.sw.xml (The face_info.xml is the same, but without the switch)

<?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="wrap_content"
    android:orientation="vertical" >

    <Switch
        android:id="@+id/face_sw"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:tag="face_sw"
        android:text="Enabled?"
        android:textOff="No"
        android:textOn="Yes" />

    <com.zyphronics.AF.Controls.colorpicker.ColorPickerMenuView
        android:id="@+id/face_color"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:tag="face_color" />
</LinearLayout>

即使没有在face_info_sw.xml的ColorPickerMenuView的一部分,子视图仍然没有被调用。我也试着具有相对布局本身,而不是在一个滚动视图,但这$ P $被滚动到pvented进一步添加的项目(同时也取得了自定义控件有奇怪的大小)。

Even without the "ColorPickerMenuView" part in the face_info_sw.xml, the child view is still not being called. I've also tried having the Relative Layout by itself, instead of in a scroll view, but this prevented further added items from being scrolled to (and also made custom controls have weird sizes).

任何帮助解决这将是巨大的。如果有人需要这样一个包装源(偏食兼容),如评论,我会用一个链接回复。

Any help to solve this would be great. If anyone needs a packaged source of this (eclipse compatible), as in the comments and I'll reply with a link.

推荐答案

令人失望的,没有人能回答这个问题......但是,luckly我能找到这个问题的解决方案,让其他人在那里可以添加扩展列表视图他们的片段了。

Bummer that no one was able to answer this...but, luckly I was able find a solution for this problem so others out there can add expandable list views to their fragments too.

我发现,同时检查了源$ C ​​$ C的微调解决方案(因为我想让自定义条目的微调)。在code关键的一点是它的onMeasure时,它可以测量它的所有孩子......好了,到了15 pre定义的限制,但衡量孩子才是重点。

I found the solution while checking out the source code for the spinner (because I wanted to make a spinner with custom entries). The key point in the code was in it's "onMeasure" when it measures all of it's children...well, up to a pre-defined limit of 15, but measuring the children is the main point.

=解决方案= 当创建您的适配器,您需要通过您的父视图。这是关键,因为它是你必须认为从适配器(仅限于简单的方法)的唯一纽带。

= Solution = When creating your adapter, you need to pass in your parent view. This is key because it's the only link you have to the view from the adapter (only easy way).

public Context context;
public ExpandableListView parent;
private LayoutInflater inflator;
// Only measure this many items to get a decent max height.
private static final int MAX_ITEMS_MEASURED = 15;

public ExpandableFaceList(Context context, final ExpandableListView parent)
{
    this.context = context;
    this.parent = parent;
    this.inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    mDensity = context.getResources().getDisplayMetrics().density;
}

接下来,在你的getGroupView,因为这似乎是它通常被称为唯一的事情,你需要添加下面的code:

Next, in your "getGroupView", because that seems to be the only thing which is commonly called, you'll need to add the following code:

public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent)
{
    if(convertView != null)
    {
        int nH = 0;
        if(isExpanded)
        {
            nH = measureChildrenHeight(groupPosition);
        } else
        {
            nH = convertView.getMeasuredHeight();
        }
        parent.getLayoutParams().height = (int) (nH * mDensity);

        parent.invalidate();
    }

    return convertView;
}

在上面的code中的关键部分是measureChildrenHeight,在convertView.getMeasuredHeight()只是崩溃的时候,恢复ELV。这项措施的儿童code是如下:

The key part in the above code is the "measureChildrenHeight", the "convertView.getMeasuredHeight()" is just to restore the ELV when collapsed. The measure children code is as follows:

int measureChildrenHeight(int groupPosition)
{
    int height = 0;
    View itemView = null;
    LinearLayout viewGroup = new LinearLayout(context);
    viewGroup.setOrientation(LinearLayout.VERTICAL);

    final int widthMeasureSpec =
    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    final int heightMeasureSpec =
    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

    // Make sure the number of items we'll measure is capped. If it's a huge data set
    // with wildly varying sizes, oh well.
    int start = 0;//Math.max(0, getSelectedItemPosition());

    final int end = Math.min(getChildrenCount(groupPosition), start + MAX_ITEMS_MEASURED);
    final int count = end - start;
    start = Math.max(0, start - (MAX_ITEMS_MEASURED - count));
    for (int i = start; i < end; i++) 
    {
        itemView = getChildView(groupPosition, i, (i+1 == end), itemView, viewGroup);
        if (itemView.getLayoutParams() == null)
        {
            itemView.setLayoutParams(new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
        }
        itemView.measure(widthMeasureSpec, heightMeasureSpec);

        if(i+1 != end)
        height += itemView.getMeasuredHeight();//Math.max(height, itemView.getMeasuredHeight());
    }

    return height;
}

注:我不得不调整code排除最后一个项目的高度,因为它被添加下面的最后一项额外的空间。如果您有不同身高的儿童,可能会有麻烦。我还是让孩子们/组头下面的一些空白,但这是情有可原(不像previous量,这是3-4儿童高)。

Note: I had to adjust the code to exclude the last item's height because it was adding extra space below the last item. If you have children of different height, there might be trouble. I still get some empty space below the children/ group header, but it's excusable (unlike the previous amount, which was 3-4 children tall).

这篇关于getChildView不会被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆