ExpandableListView onChildClick不会触发(在主/详细流程中)

时间:2015-05-11 10:45:28

标签: android android-fragments expandablelistview expandablelistadapter

我知道很多人都提过类似的问题,但他们的解决方案都不适合我。

我有主/详细信息流expandable listlist。我可以单击这些组并展开它们,但我无法点击该项 n。

我已将它们设置为可选择(起初我认为这是问题),它们上没有任何checkboxes或图像,只是纯文本。我甚至将该文本设置为focusable(因为可聚焦元素似乎是其他人的问题)。

这就是我所拥有的: 自定义BaseExpandableAdapter

public class CabinetAndRacksExpandAdapter extends BaseExpandableListAdapter {
//(some fields that probably aren't relevant)
@Override
public int getGroupCount() {
        return cabinets.size();
    }
(more override methods here, probably not relevant)

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.listrow_cabinet, null);
    }
    Cabinet cabinet = (Cabinet) getGroup(groupPosition);
    ((CheckedTextView) convertView).setText(cabinet.toString());
    ((CheckedTextView) convertView).setChecked(isExpanded);
    return convertView;
    }

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    final Rack rack = (Rack) getChild(groupPosition, childPosition);

    TextView text = null;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.listrow_rack, null);
    }
    final View view = convertView;
    text = (TextView) convertView.findViewById(R.id.textView1);
    text.setText(rack.toString());
    return convertView;
   }

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

我还有一个fragment(主/详细信息流中的列表片段)。它应该听取孩子和组的点击,因此它实现了listeners

public class CabinetListFragment extends Fragment implements ExpandableListView.OnChildClickListener, ExpandableListView.OnGroupClickListener{
    //(some stuff that's probably not relevant)

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_cabinet_list, container, false);

        listView = (ExpandableListView) rootView;
        listView.setOnChildClickListener(this);
        listView.setOnGroupClickListener(this);

        Bundle extras = getActivity().getIntent().getExtras();
        if(extras != null)
        {
            String orderId = extras.getString(CabinetListActivity.ARG_ORDER_ID);
            order = service.getOrderFromId(service.intFromString(orderId));
        }
        CabinetAndRacksExpandAdapter adapter = new CabinetAndRacksExpandAdapter(getActivity(), service.getCabinetsForOrder(order));
        listView.setAdapter(adapter);

        return rootView;
    }

 @Override
 public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
        Log.d("CabinetListFragment", "onChildClick");
        mCallbacks.onChildSelected(groupPosition, childPosition);
        return true;
    }

 @Override
 public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id)
    {
        Log.d("CabinetListFragment", "onGroupClick");
        mCallbacks.onGroupSelected(groupPosition);
        return false;
    }

/**
 * A callback interface that all activities containing this fragment must
 * implement. This mechanism allows activities to be notified of item
 * selections.
 */
public interface Callbacks {
    /**
         * Callback for when an item has been selected.
         */
        public void onChildSelected(int groupPosition, int childPosition);
        public void onGroupSelected(int groupPosition);
    }

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Activities containing this fragment must implement its callbacks.
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException("Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
    }
}

此片段属于一个实现Callback的Activity:

public class CabinetListActivity extends FragmentActivity
    implements CabinetListFragment.Callbacks{

/**
 * Whether or not the activity is in two-pane mode, i.e. running on a tablet
 * device.
 */
private boolean mTwoPane;

public static final String ARG_ORDER_ID = "order_id";
private Service service;
private Order order;
private String orderId;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cabinet_list);
    service = Service.getInstance();

    if (findViewById(R.id.cabinet_detail_container) != null) {
        mTwoPane = true;
    }

    Bundle extras = getIntent().getExtras();
    if(extras != null)
    {
        String orderId = extras.getString(ARG_ORDER_ID);
        order = service.getOrderFromId(service.intFromString(orderId));
        this.orderId = orderId;
    }
}

/**
 * Callback method from {@link CabinetListFragment.Callbacks}
 * indicating which item was selected.
 */
@Override
public void onChildSelected(int groupPosition, int childPosition) {
    if (mTwoPane) {
        // In two-pane mode, show the detail view in this activity by
        // adding or replacing the detail fragment using a
        // fragment transaction.
        Bundle arguments = new Bundle();
        arguments.putString(CabinetDetailFragment.ARG_CHILD_ID, childPosition+"");
        arguments.putString(CabinetDetailFragment.ARG_GROUP_ID, groupPosition+"");
        arguments.putBoolean(CabinetDetailFragment.ARG_RACKMODE, true);
        CabinetDetailFragment fragment = new CabinetDetailFragment();
        fragment.setArguments(arguments);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.cabinet_detail_container, fragment)
                .commit();

    } else {
        // In single-pane mode, simply start the detail activity
        // for the selected item ID.
        Log.d("CabinetListActivity", "show rack");
        Intent detailIntent = new Intent(this, CabinetDetailActivity.class);
        detailIntent.putExtra(CabinetDetailFragment.ARG_CHILD_ID, childPosition + "");
        detailIntent.putExtra(CabinetDetailFragment.ARG_GROUP_ID, groupPosition+"");
        detailIntent.putExtra(CabinetDetailFragment.ARG_RACKMODE, true);
        startActivity(detailIntent);
    }
}

@Override
public void onGroupSelected(int groupPosition) {
    if (mTwoPane) {
        // In two-pane mode, show the detail view in this activity by
        // adding or replacing the detail fragment using a
        // fragment transaction.
        Bundle arguments = new Bundle();
        arguments.putString(CabinetDetailFragment.ARG_GROUP_ID, groupPosition+"");
        arguments.putString(CabinetDetailFragment.ARG_ORDER_ID, orderId);
        arguments.putBoolean(CabinetDetailFragment.ARG_RACKMODE, false);
        CabinetDetailFragment fragment = new CabinetDetailFragment();
        fragment.setArguments(arguments);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.cabinet_detail_container, fragment)
                .commit();
    } else {
        // In single-pane mode, simply start the detail activity
        // for the selected item ID.
        Intent detailIntent = new Intent(this, CabinetDetailActivity.class);
        detailIntent.putExtra(CabinetDetailFragment.ARG_GROUP_ID, groupPosition+"");
        detailIntent.putExtra(CabinetDetailFragment.ARG_ORDER_ID, orderId);
        detailIntent.putExtra(CabinetDetailFragment.ARG_RACKMODE, false);
        startActivity(detailIntent);
        }

    }
//(more stuff that's probably not relevant)
}

我无法看到childClick事件与GroupClick事件的不同之处。 如上所述,GroupClick触发并按预期处理,但childClick甚至没有被触发(我尝试从片段中的onChildClick记录)。 顺便说一下,这个方法是返回true还是false(当然,因为它永远不会被调用)似乎没有任何区别。

我已尝试直接在childView上创建一个监听器,这样可行。但是我需要在片段或活动(最好是活动,但它应该是听取事件的片段)中点击,这样就不会做。

为什么我的fragmentonChildClick事件被注册为listener时未收到通知?该事件是否因某种原因从未被解雇?还是在其他地方处理?

3 个答案:

答案 0 :(得分:2)

只是在黑暗中拍摄,但你是否在那些不相关的方法中实施

int getChildrenCount(int groupPosition) {
  // Return whatever the children's count is
}

public boolean areAllItemsEnabled() {
  return true;
}

在布局XML R.layout.listrow_rack中,您是否已经禁用该项目,或者将一个点击监听器关联到静默激发?

答案 1 :(得分:1)

也许,你想要做的是类似的事情:

public class FaltasFragmentActivity extends Activity {

    //Lista de faltas
    private ExpandableListView mExpandalbeView;
    private ExpandableListAdapter listAdapter; 
    private int posicion;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.conduccion_faltas);

        mExpandalbeView = (ExpandableListView) findViewById(R.id.expandable_faltas);

        mExpandalbeView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                // Codigo para cerra el ultiom grupo abierto antes de abrir el nuevo
                Toast.makeText(FaltasFragmentActivity.this, "pulsado group: " + groupPosition, Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        // Listview on child click listener
        mExpandalbeView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                Toast.makeText(FaltasFragmentActivity.this, "pulsado child: (" + groupPosition + ", " + childPosition + ")", Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        // Listview Group expanded listener
        mExpandalbeView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                Toast.makeText(FaltasFragmentActivity.this, "pulsado expand", Toast.LENGTH_SHORT).show();
            }
        });

        // Listview Group collasped listener
        mExpandalbeView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {
                Toast.makeText(FaltasFragmentActivity.this, "pulsado collapse", Toast.LENGTH_SHORT).show();
            }
        });

        listAdapter = new ExpandableListAdapter(FaltasFragmentActivity.this, root, posicion, filtroBusqueda);
        mExpandalbeView.setAdapter(listAdapter);
    }
}

ExpandableListAdapter(...)的位置:

public class ExpandableListAdapter extends BaseExpandableListAdapter{...}

这对我有用! 希望这有帮助!

答案 2 :(得分:0)

好的,这就是问题所在:

这是我的listrow_rack:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="40dp"
android:clickable="true"
android:orientation="vertical"
android:paddingLeft="40dp"
tools:context=".OrdreDetailActivity" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawablePadding="5dp"
    android:gravity="center_vertical"
    android:text="@string/hello_world"
    android:textSize="14sp"
    android:textStyle="bold">
</TextView>

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@android:color/black" />

问题在于这个特定的界限:

    android:clickable="true"

我不知道为什么,但也许它会增加一个听众,或者可能是出于其他原因。但当我删除它时,它可以工作。

道具指向Andras Baláz Lathja指向正确的方向。