Android Fragment 按键监听

Fragment 中是没有监听按键的方法的,但是Fragment是寄托于Activity的,只要在Activity中将监听到的按键传递给Fragment就行,网络上大部分都是让Fragment 获得焦点,再添加一个按键监听器,这样就能监听到了

	@Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //return super.onCreateView(inflater, container, savedInstanceState);
        if(rootView==null){
            rootView=  inflater.inflate(R.layout.framgment1, container, false);
        }
        rootView.setFocusable(true);
        rootView.setFocusableInTouchMode(true);
        //然后在写这个监听器
        rootView.setOnKeyListener(backlistener);
        return rootView;
    }
 
    private View.OnKeyListener backlistener = new View.OnKeyListener() {
        @Override
        public boolean onKey(View view, int i, KeyEvent keyEvent) {
            if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
                 //这边判断,如果是back的按键被点击了   就自己拦截实现掉  
                if (i == KeyEvent.KEYCODE_BACK) {
                    Toast.makeText(UIUtils.getContext(), "BACK拦截", Toast.LENGTH_SHORT).show();
                    return true;//表示处理了
                }
            }
            return false;
        }
    };

上面网络上的方法都需要寻求focus,即Fragment抢占焦点,如果不抢占焦点,则setOnKeyListener() 不起作用,无法监听到按键响应,但这样 Fragment中的子控件无法获得焦点,尴尬

Fragment是依托再Activity中的,所以实现方法很简单,只需要将Activity监听到的按键值传递过去就行

首先封装一个BaseFragment

public abstract class BaseFragment extends Fragment {
    abstract public boolean onFragmentKeyDown(int keyCode);
}

里面有一个onFragmentKeyDown 方法,这个方法就是接收Activity传递过来的keyCode,再让fragment继承这个BaseFragment

public class USBPictureFragment extends BaseFragment {

    private Context mContext;
    private View rootView;
    
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        Log.d("lyt", "onAttach: ");
        this.mContext = context;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("lyt", "onCreate: ");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(rootView==null){
            rootView=  inflater.inflate(R.layout.fragment_usb_picture, container, false);
        }
        Log.d("lyt", "onCreateView: ");
        return rootView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        
    }
    @Override
    public boolean onFragmentKeyDown(int keyCode) {
        if (mContext == null)
            return false;
        //TODO 要处理的按键监听事件
        return false;
    }
}

在Activity中传递

通过Activity 中 dispatchKeyEvent 方法监听按键,再拿到当前显示Fragment的实例,调用这个实例的 onFragmentKeyDown() 方法将监听到的按键传递给Fragment,再Fragment中就能做相应的处理

public class MyActivity extends FragmentActivity {
	
	private TabLayoutRecyclerView wallpaper_tablelayoutRecyclerView;
    private ViewPager wallpaper_viewpager;

    public Map<String, BaseFragment> tabMap;

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

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private void initView(){
        wallpaper_tablelayoutRecyclerView = findViewById(R.id.wallpaper_tablelayoutRecyclerView);
        wallpaper_viewpager = findViewById(R.id.wallpaper_viewpager);

        tabMap = new LinkedHashMap<String, BaseFragment>();

		// 此map保存显示的fragment信息,
        tabMap.put(getResources().getString(R.string.wallpaper_local_pic), new LocalPictureFragment());
        tabMap.put(getResources().getString(R.string.wallpaper_usb_pic), new USBPictureFragment());


        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        wallpaper_tablelayoutRecyclerView.setLayoutManager(layoutManager);
        TabLayoutAdapter tabLayoutAdapter = new TabLayoutAdapter(tabMap, new TabLayoutAdapter.OnTabLayoutItemCallBackListener() {
            @Override
            public void OnItemFocusChange(View v, int position) {
                //焦点改变时,更改viewPage显示的fragment
                wallpaper_viewpager.setCurrentItem(position, false);
            }
            @Override
            public void OnItemClick(View v, int position) {
                wallpaper_viewpager.setCurrentItem(position, false);
                v.requestFocus();
            }
            @Override
            public void OnItemLongClick(View v, int position) {}
        });
        wallpaper_tablelayoutRecyclerView.setAdapter(tabLayoutAdapter);

        ViewPagerAdapter viewPageAdapter = new ViewPagerAdapter(getSupportFragmentManager(), tabMap);
        wallpaper_viewpager.setAdapter(viewPageAdapter);
    }

    @SuppressLint("RestrictedApi")
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN){
            int keyCode = event.getKeyCode();
            // 向Fragment 传递按键值
            return getShowFragment(wallpaper_viewpager.getCurrentItem()).onFragmentKeyDown(keyCode);
        }else if (event.getAction() == KeyEvent.ACTION_UP){
            //TODO 按键松开
        }
        return super.dispatchKeyEvent(event);
    }

	// 获得当前显示的fragment,通过ViewPager控件的getCurrentItem()获得当前显示的fragment
    private BaseFragment getShowFragment(int item){
        if (item==0){
            return tabMap.get(getResources().getString(R.string.wallpaper_local_pic));
        }else if (item == 1){
            return tabMap.get(getResources().getString(R.string.wallpaper_usb_pic));
        }
        return null;
    }
    
    public static void actionStart(Context context){
        Intent intent = new Intent(context, WallPaperEngineActivity.class);
        context.startActivity(intent);
    }

    private void finishActivity(){
        finish();
    }
}

你可能感兴趣的:(android,android,android,studio,java)