Android 即使显示其他片段,ViewPager onClickListener 也会做出反应

Android ViewPager onClickListener reacts even if other fragment is show

我有一个包含两个片段的 ViewPager。一个 fragment 什么都不包含,另一个 fragment 包含 gridviewImageViewsImageViews 有一组 onClickListener。 到目前为止一切正常......但是当我在什么都不包含的片段上并点击其他片段的 onClickListener 某处时,即使它的元素不可见,imagview 也会对我的点击做出反应。

我可以更改我的 onClickListener 以便它检查显示的是哪个片段,但这真的是我应该做的吗???感觉有点脏

这是我的 FragmentStatePageAdapter

public class OwnPagerAdapter extends FragmentStatePagerAdapter{

private BackgroundImage backgroundImage = new BackgroundImage();
private Apps apps = new Apps();
private Home_Screen ac;

public OwnPagerAdapter(FragmentManager fm, Home_Screen activity) {
    super(fm);
    this.ac = activity;
}

@Override
public Fragment getItem(int position) {
    if(position == 0) {
    return backgroundImage;
    }else if(position == 1) {

        return  this.apps;
    }
    return null;
}

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

这是我的 BaseAdapter

public class AppAdapter extends BaseAdapter {
private AppLauncher launcherListener = new AppLauncher();
private ArrayList<ApplicationInfo> appList;
private Context ctx;
public AppAdapter(ArrayList<ApplicationInfo> listOfApps, Context ctx){
    this.appList = listOfApps;
    this.ctx = ctx;
}

@Override
public int getCount() {
    return this.appList.size();
}

@Override
public Object getItem(int i) {
    ImageView v = new ImageView(this.ctx);
    v.setImageDrawable(this.appList.get(i).loadIcon(this.ctx.getPackageManager()));
    return v;
}

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

@Override
public View getView(final int i, View view, ViewGroup viewGroup) {
    if(view != null){
        ((ImageView) view).setImageDrawable(this.appList.get(i).loadIcon(this.ctx.getPackageManager()));
        view.setTag(i);

        return view;
    }

    ImageView v = new ImageView(this.ctx);

    v.setImageDrawable(this.appList.get(i).loadIcon(this.ctx.getPackageManager()));
    v.setScaleType(ImageView.ScaleType.CENTER);
    v.setOnClickListener(launcherListener);
    v.setTag(i);
    return v;

}



private class AppLauncher implements View.OnClickListener {

    @Override
    public void onClick(View view) {

        ctx.startActivity(ctx.getPackageManager().getLaunchIntentForPackage(appList.get((int) view.getTag()).packageName));
    }
}
}

那是我的片段class

public class Apps extends Fragment implements LoaderManager.LoaderCallbacks<ArrayList<ApplicationInfo>>{


private GridView gridview;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    getLoaderManager().initLoader(1, null, this).forceLoad();
    View rootView = inflater.inflate(R.layout.fragment_apps, container, false);
    this.gridview = (GridView)rootView.findViewById(R.id.apptable);

    return rootView;


}

@Override
public Loader<ArrayList<ApplicationInfo>> onCreateLoader(int id, Bundle args) {
    return new AppLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<ArrayList<ApplicationInfo>> loader, ArrayList<ApplicationInfo> data) {
    Toast.makeText(getActivity(), "Done with loading Apps", Toast.LENGTH_LONG).show();
    this.gridview.setAdapter(new AppAdapter(data,getActivity()));
}

@Override
public void onLoaderReset(Loader<ArrayList<ApplicationInfo>> loader) {

}
}

虽然我找不到您问题的任何具体原因,但我必须建议一种更简洁的方法来实现您正在寻找的相同结果,使用内部 class 只是为了捕获点击事件是肮脏的,而且是不必要的.使用此方法很有可能也能解决您的问题。

为什么不在整个 gridview 上使用 OnItemClickListener,而不是使用实现 OnClickListener 然后手动为每个项目设置它的 AppLauncher class?它将处理每个项目的点击事件,并且仅特定于您的 gridview 中的项目,因此您不必像使用内部 classes 那样担心任何泄漏。

在您的片段中实现 OnItemClickListener :

public class Apps extends Fragment implements LoaderManager.LoaderCallbacks<ArrayList<ApplicationInfo>>, OnItemClickListener

然后在片段的 onCreate 中简单地将适配器设置为 gridview:

gridview.setOnItemClickListener(this);

并实施必要的方法:

@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    getActivity().startActivity(getActivity().getPackageManager().getLaunchIntentForPackage(appList.get(position).packageName));
}

现在您可以从 gridview 的适配器中删除 OnClickListener 逻辑,它应该可以正常工作,我猜它也可以解决您的问题,即使不能,嘿,至少您最终会得到一个更清晰的代码。

关于您的代码,我觉得奇怪的另一件事是您覆盖了 getItemId() 但始终 return 0,请确保这是您正在寻找的正常行为,因为我不确定它是。

祝你好运。