【问题标题】:DrawerLayout with ListView representing actions - how to call action methods on a View?用 ListView 表示动作的 DrawerLayout - 如何在视图上调用动作方法?
【发布时间】:2015-07-19 22:24:17
【问题描述】:

我已经为我的问题准备了a simple test project at GitHub

它基于the well-known Navigation Drawer Example by Google - 由右侧抽屉扩展,在 ListView 中具有与音乐相关的操作:

动作都定义在res/values/strings.xml中:

<string-array name="music_actions">
    <item>Play</item>
    <item>Pause</item>
    <item>Stop</item>
    <item>Shuffle</item>
</string-array>

<integer-array name="music_icons">
    <item>@drawable/ic_play_arrow_black_24dp</item>
    <item>@drawable/ic_pause_black_24dp</item>
    <item>@drawable/ic_stop_black_24dp</item>
    <item>@drawable/ic_shuffle_black_24dp</item>
</integer-array>

这是从资源中读取它们的代码(效果很好):

public class MainActivity extends AppCompatActivity {
    private String[] mActions;
    private int[] mIcons;

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

        mActions = getResources().getStringArray(R.array.music_actions);

        TypedArray ta = getResources().obtainTypedArray(R.array.music_icons);
        mIcons = new int[ta.length()];
        for (int i = 0; i < mIcons.length; i++)
                mIcons[i] = ta.getResourceId(i, R.drawable.ic_menu_black_24dp);
        ta.recycle();

我的问题是:

从ListView的监听器中的onItemClick方法——如何调用Fragment中的对应方法?

我只看到了丑陋的方法,比如这里有一个硬编码的switch 声明:

    mRightDrawer.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mActions) {
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView view = (TextView) super.getView(position, convertView, parent);
            view.setCompoundDrawablesWithIntrinsicBounds(mIcons[position], 0, 0, 0);
            return view;
        }
    });
    mRightDrawer.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (mActiveFragment instanceof GameFragment) {
                GameFragment fragment = (GameFragment) mActiveFragment;
                switch (position) {
                case 0:
                    fragment.playMusic(); // and then this calls myView.playMusic();
                    break;
                case 1:
                    fragment.pauseMusic(); // calls myView.pauseMusic();
                    break;
                }
            }

            mDrawerLayout.closeDrawer(mRightDrawer);
        }
    });

这很难看,因为我必须跟踪我当前活动的 Fragment,然后使用包装器方法最终调用我的自定义 View 上的方法。

如何改善这种情况,我是否应该在自定义视图中使用BroadcastReceiver

我希望,我可以在我的资源中定义 icon + title + action,然后直接使用它们。

更新:

目前我正在使用BroadcastReceiver,但想知道这是否是一个合适的解决方案(或者可能过于繁重?)。

在我的片段中我调用:

@Override
public void onResume() {
    super.onResume();

    myView.register();
}

@Override
public void onPause() {
    super.onPause();

    myView.unregister();
}

在我的自定义视图中,我有:

public class MyView extends View {

    public final static String ACTION_PLAY    = "de.afarber.myapp.play";
    public final static String ACTION_PAUSE   = "de.afarber.myapp.pause";
    public final static String ACTION_STOP    = "de.afarber.myapp.stop";
    public final static String ACTION_SHUFFLE = "de.afarber.myapp.shuffle";

   private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              String action = intent.getAction();
              if (ACTION_PLAY.equals(action))
                  playMusic();
              else if (ACTION_PAUSE.equals(action))
                  pauseMusic();
              else if (ACTION_STOP.equals(action))
                  stopMusic();
              else if (ACTION_SHUFFLE.equals(action))
                  shuffleMusic();
          }
    };

    public void register() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_PLAY);
        filter.addAction(ACTION_PAUSE);
        filter.addAction(ACTION_STOP);
        filter.addAction(ACTION_SHUFFLE);
        getContext().registerReceiver(mMessageReceiver, filter);
    }

我希望为 Fragments 提供某种“上下文菜单” - 定义 title + icon + action - 然后可以由右侧 Drawer 中的 actions-ListView 使用...

    public void unregister() {
        getContext().unregisterReceiver(mMessageReceiver);
    }

【问题讨论】:

    标签: android android-fragments android-listview android-resources android-broadcast


    【解决方案1】:

    广播适用于我基于 DrawerLayout 的应用程序,但为了更好的安全性和效率,我已切换到 LocalBroadcastManager -

    MainActivity.java(右操作抽屉菜单发送广播):

        mRightDrawer.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String action = mActions[position];
                Intent intent = new Intent(action);
                //intent.putExtra("message", "data");
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
                mDrawerLayout.closeDrawer(mRightDrawer);
            }
        });
    

    PlanetFragment.java(活动片段接收应用内部广播):

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ...
        mManager = LocalBroadcastManager.getInstance(getActivity());
    
        mFilter = new IntentFilter();
        mFilter.addAction(ACTION_PLAY);
        mFilter.addAction(ACTION_PAUSE);
        mFilter.addAction(ACTION_STOP);
        mFilter.addAction(ACTION_SHUFFLE);
        ...
    }
    
    @Override
    public void onResume() {
        super.onResume();
        mManager.registerReceiver(mMessageReceiver, mFilter);
    }
    
    @Override
    public void onPause() {
        super.onPause();
        mManager.unregisterReceiver(mMessageReceiver);
    }
    

    【讨论】:

    • 如果您想使用其他 3 方库,则很少。来自绿色机器人和 rx android 的 EventBus。
    猜你喜欢
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多