Android 使用自定义适配器的片段中的OnItemSelectedListener

Android 使用自定义适配器的片段中的OnItemSelectedListener,android,android-listview,android-fragments,Android,Android Listview,Android Fragments,所以我已经玩了几天了,但似乎无法让它发挥作用。我有一个显示片段的活动,该片段是我使用ViewPager翻页的片段列表的一个成员。片段本身由一个TextView和一个ListView组成。ListView通过自定义适配器填充自身 我试图做的是将一个OnItemSelected事件传递回处理它的片段。对我来说,在这里显示代码可能更好 这就是活动 public class DialogInventory extends FragmentActivity implements OnItemSelecte

所以我已经玩了几天了,但似乎无法让它发挥作用。我有一个显示片段的活动,该片段是我使用ViewPager翻页的片段列表的一个成员。片段本身由一个TextView和一个ListView组成。ListView通过自定义适配器填充自身

我试图做的是将一个OnItemSelected事件传递回处理它的片段。对我来说,在这里显示代码可能更好

这就是活动

public class DialogInventory extends FragmentActivity implements OnItemSelectedListener {

ViewPager viewPager;
Pager pager;

@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.dialog_inventory);

    List<Fragment> fragList = new Vector<Fragment>();
    fragList.add(Fragment.instantiate(this, FragmentOne.class.getName()));
    fragList.add(Fragment.instantiate(this, FragmentTwo.class.getName()));
    pager = new Pager(getSupportFragmentManager(), fragList);

    viewPager = (ViewPager) findViewById(R.id.pagerMain);
    viewPager.setAdapter(pager);

    listMain = (ListView) findViewById(R.id.listMain);
    listMain.setOnItemSelectedListener(this);
}

public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    switch (viewPager.getCurrentItem()) {
        case 0:
            FragmentOne fragOne = new FragmentOne();
            fragOne.onItemSelected(parent, view, pos, id);
            break;
        case 1:
            FragmentTwo fragTwo = new FragmentTwo();
            fragTwo.onItemSelected(parent, view, pos, id);
            break;
    }
}
public void onNothingSelected(AdapterView<?> arg0) {
}
公共类对话框Inventory扩展了FragmentActivity实现了MSelectedListener{
查看页面查看页面;
寻呼机;
@凌驾
创建时受保护的void(捆绑){
super.onCreate(bundle);
setContentView(R.layout.dialog\u目录);
List fragList=新向量();
add(Fragment.instantiate(这是FragmentOne.class.getName());
add(Fragment.instantiate(这是FragmentTwo.class.getName());
寻呼机=新寻呼机(getSupportFragmentManager(),fragList);
viewPager=(viewPager)findViewById(R.id.pagerMain);
设置适配器(寻呼机);
listMain=(ListView)findViewById(R.id.listMain);
setOnItemSelectedListener(此);
}
已选择公共位置(AdapterView父项、视图、整数位置、长id){
开关(viewPager.getCurrentItem()){
案例0:
FragmentOne FragmentOne=新的FragmentOne();
fragOne.onItemSelected(父项、视图、位置、id);
打破
案例1:
FragmentTwo fragmentwo=新的FragmentTwo();
fragTwo.onItemSelected(父级、视图、位置、id);
打破
}
}
未选择公共无效(AdapterView arg0){
}
这是片段:

public class FragmentOne extends Fragment implements OnItemSelectedListener {

View view;
ListView listMain;
ArrayList<String> invItems = new ArrayList<String>();

public FragmentOne() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
    view = inflater.inflate(R.layout.fragment_one, viewGroup, false);

    listMain = (ListView) v.findViewById(R.id.listMain);
    listMain.setAdapter(new AdapterItem(getActivity().getApplicationContext(),
        R.layout.tile_item, invItems));
    listMain.setOnItemSelectedListener(this);
    return view;
}
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
    Log.i("Test", "hit");
}
公共类FragmentOne扩展了片段实现OnItemSelectedListener{
视图;
ListView listMain;
ArrayList invItems=新的ArrayList();
公共碎片1(){
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组、视图组、捆绑包){
视图=充气机。充气(R.layout.fragment\u one,视图组,false);
listMain=(ListView)v.findViewById(R.id.listMain);
listMain.setAdapter(新的AdapterItem(getActivity().getApplicationContext()),
R.layout.tile_项,m);
setOnItemSelectedListener(此);
返回视图;
}
已选择公共位置(AdapterView父项、视图、整数位置、长id){
Log.i(“测试”、“命中”);
}
为了简洁起见,省略了一些行。让我们假设片段正确显示并且一切正常。唯一不能正常工作的是活动中的OnItemSelected事件根本没有触发……更不用说片段中的OnItemSelected事件了。我在这里做错了什么

编辑:ListView必须在各自的片段中(因为它们将在不同的活动以及上面列出的活动中单独显示)。这里最大的问题是,我无法在我的活动中设置OnItemSelectedListener,因此事件永远不会被触发。我已经完成并运行了指向该点的所有代码,只是OnItemSelectedListener不起作用

Edit2:我明天会给这个问题增加一个悬赏。有鉴于此,我认为我会更明确地说明正确答案的范围。正确答案不会建议对UI布局或表示方式进行任何重大更改。正确答案会将选定的事件传递到片段并在片段中进行处理。答案不会Don’不要让我用一行又一行的代码来完成我认为只需几行就可以完成的事情。更优雅的答案显然更吸引人。感谢所有看过这篇文章的人


这里的问题是我在我的活动中得到一个NPE。我如何将它指向一个与它所在的类的布局不同的布局中的ListView。

在哪里使用ListView.setOnItemSelectedListener(this)?您需要显式地通知ListView您的活动应该控制UI行为

在您的片段中添加:

listMain.setOnItemSelectedListener(this);

我也一直在尝试做类似的事情。问题在于,在活动中没有一个实例可以用来设置选定的侦听器。我个人尝试了所有我能想到的方法来实现这一点。包括:

list = (ListView) vp.getRootView().findViewById(R.id.listMain);
list.setOnItemSelectedListener(this);
其中list是您实例化的listview,然后将其设置为片段中的列表。这种方法的问题是,当您尝试将侦听器设置为该列表时,您会得到一个NPE。如果您找到此问题的答案,请将其发布在此处。这将对我有很大帮助


有人建议我采取一种新的方法,每次调用viewpager时都重新创建列表(没有实际分页..即,在视图实际上从未更改的情况下创建滑动的假象)我已经有人建议使用ListFragment…ListFragment会很好,但是除了ListFragment之外,您不能在布局中包含任何其他内容。

在FragmentActivity中,您可以使用一个静态方法来完成这项工作,而不是使用OnItemSelectedListener。onItemSelected()(在片段中)。

创建自己的接口,回调可能是最好的解决方案。在我的应用程序中,我做了如下操作:

public class ModuleFragment extends ListFragment {
   //...
    private OnModuleSelectedListener mdListener;

// this method makes sure my activity implements my interface. If not I show an error
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mdListener = (OnModuleSelectedListener) activity;
            Log.d(TAG, "OnModuleSelectedListener Implemented !");
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                + " must implement OnSqSelectedListener");
        }
    }
// This is the standard onListItemClick, I use it to get data I need and give them to the Listener
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        l.getItemAtPosition(position);
        HashMap<String, String> map = (HashMap<String, String>) l
            .getItemAtPosition(position);
        mdId = map.get("id");
        mdName = map.get("name");
        mdListener.onModuleSelected(mdId,mdName);

    }

    public interface OnModuleSelectedListener {
        public void onModuleSelected(String mdId, String mdName);
    }
}

希望对您有所帮助。这是我能给您的最接近您的问题的答案。

在片段的父活动中实现接口将解决您的问题。例如,TestFragment包含一个名为TestFragmentListener的接口。在父活动中实现此侦听器接口并保留Int的引用片段中的erface执行回调。OnItemSelectedListener方法执行对父活动的回调,并正常处理其余活动。请参阅sam
public class Main extends Activity implements OnModuleSelectedListener{
//...
    public void onModuleSelected(String mdId, String mdName) {
            //.. I do whatever I want with what I get from the list
    }
}
public final class TestFragment extends Fragment {

    TextView title;
    ListView listView;
    TestFragmentListener mActivity;
    TestAdapter adapter;

    public interface TestFragmentListener {
        public void onItemSelected(Object o);
    }

    public static TestFragment newInstance(String content) {
        TestFragment fragment = new TestFragment();
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {

        try {
            mActivity = (TestFragmentListener) activity;

        } catch (ClassCastException e) {
            Log.e("Invalid listerer", e.getMessage());
        }

        super.onAttach(activity);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mActivity = null;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View vw = inflater.inflate(R.layout.layout, container, false);

        title = (TextView) vw.findViewById(R.id.textView1);
        listView = (ListView) vw.findViewById(R.id.listView1);

        return vw;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        TestAdapter adapter = new TestAdapter();

        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
            }
        });

        listView.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int arg2, long arg3) {
                mActivity.onItemSelected(arg2);

            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });
        super.onActivityCreated(savedInstanceState);
    }
private class TestAdapter extends BaseAdapter {

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

        @Override
        public Object getItem(int arg0) {
            return null;
        }

        @Override
        public long getItemId(int arg0) {
            return arg0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup container) {

            TextView tv = new TextView((Activity) mActivity);
            tv.setText(Integer.toString(position));
            return tv;
        }
    }

}