5

そのため、私はこれを数日間いじっていますが、うまく機能しないようです。フラグメントを表示するアクティビティがあり、そのフラグメントは、ViewPager を使用してページングするフラグメントのリストのメンバーです。Fragment 自体は、TextView と ListView で構成されています。ListView は、カスタム アダプタからデータを取り込みます。

私がやろうとしているのは、OnItemSelected イベントを、それが処理される Fragment に戻すことです。先に進んでここにコードを表示する方がおそらく良いでしょう。

これがアクティビティです

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

簡潔にするために、一部の行は省略されています。Fragments が正しく表示され、すべてが機能すると仮定してみましょう。正しく動作していない唯一のことは、アクティビティの OnItemSelected イベントがまったく発生していないことです...フラグメントの OnItemSelected イベントはなおさらです。ここで何が間違っていますか?

編集: ListViews はそれぞれの Fragments にある必要があります (上記の別のアクティビティと同様に個別に表示されるため)。ここでの最大の問題は、Activity で OnItemSelectedListener を設定できないため、イベントが発生しないことです。その時点までのすべてのコードを実行して実行していますが、機能しないのは OnItemSelectedListener だけです。

Edit2: 明日、この質問に報奨金を追加します。それを踏まえて、私は正解の範囲についてより暗黙的になると思いました. 正解は、UI のレイアウトや表示に劇的な変更を示唆するものではありません。正解は OnItemSelected イベントを Fragment に渡し、そこで処理されます。答えは、コードの行ごとにアクティビティをロードして、ほんの数行で実行できると感じることを達成することではありません。よりエレガントな答えは、明らかにより魅力的です。これを見てくれている人に感謝します。

ここでの問題は、アクティビティで NPE が発生することです。クラスのレイアウトとは異なるレイアウトに存在する ListView を指すにはどうすればよいですか。

4

5 に答える 5

2

どこで使用しますlistView.setOnItemSelectedListener(this)か? アクティビティが UI の動作を制御する必要があることを ListView に明示的に通知する必要があります...

そしてあなたのフラグメントに以下を追加してください:

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

独自のインターフェイスを作成し、Callback がおそらく最適なソリューションです。私のアプリでは、次のようなことをしました:

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 が発生することです。これに対する答えが見つかったら、ここに投稿してください。それは私を大いに助けるでしょう。

ビューページャーが呼び出されるたびに新しいアプローチを取り、リストを再作成することを人々に提案してもらいました(実際にはページングせずに..つまり、実際にはビューが変更されないのにスワイプの錯覚を作成します)。 ListFragment の使用を提案する人がいたら... ListFragment は便利ですが、ListFragment 以外をレイアウトに含めることはできません。

于 2012-07-17T22:00:08.607 に答える
0

フラグメントの親アクティビティにインターフェイスを実装すると、問題が解決します。例えば。TestFragment には、TestFragmentListener というインターフェイスが含まれています。このリスナー インターフェイスを親アクティビティに実装し、Fragment でインターフェイスの参照を保持して callback.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 に答える
0

FragmentActivity では、OnItemSelectedListener を使用する代わりに、おそらく静的メソッドを使用してジョブを実行できます。そして、このメソッドをonItemSelected() (フラグメント内) で呼び出します。

于 2012-07-22T17:16:13.653 に答える