5

所以我已经玩了几天了,但似乎无法让它发挥作用。我有一个显示片段的活动,并且该片段是我使用 ViewPager 翻页的片段列表的成员。Fragment 本身由 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) {
}

这是片段:

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");
}

为简洁起见,省略了一些行。让我们假设片段正确显示并且一切正常。唯一不能正常工作的是 Activity 中的 OnItemSelected 事件根本没有触发……更不用说片段中的 OnItemSelected 事件了。我在这里做错了什么?

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

编辑2:我明天会为这个问题增加一个赏金。鉴于此,我认为我会在正确答案的范围上更加隐含。正确的答案不会暗示 UI 布局或呈现方式有任何显着变化。正确答案会将 OnItemSelected 事件传递给 Fragment 并在那里进行处理。答案不会让我用一行又一行的代码加载我的 Activity 来实现我认为只需几行就可以做到的事情。更优雅的答案显然更具吸引力。感谢任何看到这个的人。

这里的问题是我在我的活动中获得了 NPE。如何将它指向一个 ListView,该 ListView 存在于与其所在类的布局不同的布局中。

4

5 回答 5

2

你在哪里使用listView.setOnItemSelectedListener(this)?您需要明确通知 ListView 您的 Activity 应该控制 UI 行为...

并在您的片段中添加:

listMain.setOnItemSelectedListener(this);
于 2012-07-17T17:21:36.093 回答
1

创建自己的界面,回调可能是最好的解决方案。在我的应用程序中,我做了这样的事情:

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);
    }
}

这是我的活动:

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
    }
}

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

于 2012-07-24T12:52:46.467 回答
0

我也一直在尝试做类似的事情。问题在于您在活动中没有用于设置 onitemselected 侦听器的实例。我个人尝试了我能想到的一切来让它发挥作用。包含:

list = (ListView) vp.getRootView().findViewById(R.id.listMain);
list.setOnItemSelectedListener(this);

其中 list 是您实例化的列表视图,然后设置为片段中的列表。这种方法的问题在于,当您尝试将侦听器设置为此时,您会得到 NPE。如果您找到此问题的答案,请在此处发布。这对我有很大帮助。

我有人建议我采用一种新方法,每次调用 viewpager 时都重新创建列表(实际上没有分页..即创建滑动的错觉,而实际上视图永远不会改变),我已经如果有人建议使用 ListFragment... ListFragment 会很好,但是您不能在布局中包含除 ListFragment 之外的任何其他内容。

于 2012-07-17T22:00:08.607 回答
0

在您的 FragmentActivity 中,也许您可​​以使用静态方法来完成这项工作,而不是使用 OnItemSelectedListener。并在onItemSelected()中调用此方法(在片段中)。

于 2012-07-22T17:16:13.653 回答
0

在片段的父活动中实现接口将解决您的问题。例如。TestFragment 包含一个名为 TestFragmentListener 的接口。在您的父活动中实现此侦听器接口,并在 Fragment 中保存该接口的引用以执行回调。OnItemSelectedListener 方法对父活动进行回调并正常处理其余部分。请参考下面的示例代码。

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;
        }
    }

}
于 2012-07-24T16:34:44.303 回答