Android 如何刷新选项卡 change/swipe 上的图像网格视图适配器?

Android how to refresh image grid view adapter on tab change/swipe?

我是本地 android 开发的新手。我有 3 个选项卡(地图、相机、图片)。 Map正在地图上用标记显示我当前的 GPS 位置。 Camera 用于拍照,Pictures 有一个网格视图来显示从相机拍摄的已保存照片。屏幕如下所示

现在,当我从相机拍照(在第二个选项卡中)然后转到第 3 个选项卡时,图片不存在,但是当我关闭应用程序然后转到 pictures 选项卡时,图片显示。我想在滑动到 picture 选项卡时刷新 image adapter。为此,我搜索了很多文章,发现 notifyDataSetChanged() 用于此目的,因此我尝试在我的 picture class 上实现它,但它不会刷新它。

下面是我的适配器代码

public class GridViewImageAdapter extends BaseAdapter {

private Activity _activity;
private ArrayList<String> _filePaths = new ArrayList<String>();
private int imageWidth;

public GridViewImageAdapter(Activity activity, ArrayList<String> filePaths,
                            int imageWidth) {
    this._activity = activity;
    this._filePaths = filePaths;
    this.imageWidth = imageWidth;
}

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

@Override
public Object getItem(int position) {
    return this._filePaths.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    if (convertView == null) {
        imageView = new ImageView(_activity);
    } else {
        imageView = (ImageView) convertView;
    }

    // get screen dimensions
    Bitmap image = decodeFile(_filePaths.get(position), imageWidth,
            imageWidth);

    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageView.setLayoutParams(new GridView.LayoutParams(imageWidth,
            imageWidth));
    imageView.setImageBitmap(image);

    // image view click listener
    imageView.setOnClickListener(new OnImageClickListener(position));

    return imageView;
}

class OnImageClickListener implements OnClickListener {

    int _postion;

    // constructor
    public OnImageClickListener(int position) {
        this._postion = position;
    }

    @Override
    public void onClick(View v) {
        // on selecting grid view image
        // launch full screen activity
        /*Intent i = new Intent(_activity, FullScreenViewActivity.class);
        i.putExtra("position", _postion);
        _activity.startActivity(i);*/
    }

}

/*
 * Resizing image size
 */
public static Bitmap decodeFile(String filePath, int WIDTH, int HIGHT) {
    try {

        File f = new File(filePath);

        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        final int REQUIRED_WIDTH = WIDTH;
        final int REQUIRED_HIGHT = HIGHT;
        int scale = 1;
        while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
                && o.outHeight / scale / 2 >= REQUIRED_HIGHT)
            scale *= 2;

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}}

下面是我的 picture

代码
public class Pictures extends Fragment {

private Utils utils;
private ArrayList<String> imagePaths = new ArrayList<String>();
private GridViewImageAdapter adapter;
private GridView gridView;
private int columnWidth;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.pictures, container, false);

    gridView = (GridView) rootView.findViewById(R.id.grid_view);
    utils = new Utils(getContext());

    // Initilizing Grid View
    InitilizeGridLayout();

    // loading all image paths from SD card
    imagePaths = utils.getFilePaths();

    // Gridview adapter

    adapter = new GridViewImageAdapter(getActivity(), imagePaths, columnWidth);
    /*adapter = new GridViewImageAdapter(Pictures.this, imagePaths,
            columnWidth);*/

    // setting grid view adapter
    gridView.setAdapter(adapter);

   // called the method here
    adapter.notifyDataSetChanged();


    return rootView;
}

private void InitilizeGridLayout() {

    Resources r = getResources();
    float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
            AppConstant.GRID_PADDING, r.getDisplayMetrics());

    columnWidth = (int) ((utils.getScreenWidth() - ((AppConstant.NUM_OF_COLUMNS + 1) * padding)) / AppConstant.NUM_OF_COLUMNS);

    gridView.setNumColumns(AppConstant.NUM_OF_COLUMNS);
    gridView.setColumnWidth(columnWidth);
    gridView.setStretchMode(GridView.NO_STRETCH);
    gridView.setPadding((int) padding, (int) padding, (int) padding,
            (int) padding);
    gridView.setHorizontalSpacing((int) padding);
    gridView.setVerticalSpacing((int) padding);
}}

更新 1

下面是我的 FragmentPagerAdapter 代码,它在我的 MainActivity

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                MyLocation loc = new MyLocation();
                return loc;
            case 1:
                Camera cam= new Camera();
                return cam;
           case 2:
                Pictures pic = new Pictures();
                return pic;

            default:
                return null;
        }

    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "MyLocation";
            case 1:
                return "Camera";
           case 2:
                return "Pictures";
        }
        return null;
    }
}

更新 2

我已经听从了 Valentino S. 的建议,但仍然无法在第二个选项卡中查看摄像头拍摄的图像。

下面是更新后的代码

**MainActivity.java**

public class MainActivity extends AppCompatActivity {
  ........
          public interface Updateable
          {
                public void update();
          }

 public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getItemPosition(Object object)
    {
        if(object != null && object instanceof Pictures)
        {
            Pictures p = (Pictures) object;
            p.update();
        }
        return super.getItemPosition(object);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                MyLocation loc = new MyLocation();
                return loc;
            case 1:
                Camera cam= new Camera();
                return cam;
           case 2:
                Pictures pic = new Pictures();
                return pic;

            default:
                return null;
        }

    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "MyLocation";
            case 1:
                return "Camera";
           case 2:
                return "Pictures";
        }
        return null;
     }// end charsequence

  }// end SectionsPagerAdapter 

}// end mainactivity

Pictures.java

public class Pictures extends Fragment implements MainActivity.Updateable {
........
 @Override
public void update() {
    if(adapter !=null)
    {
        adapter.notifyDataSetChanged();

    }
    else
    {
        Log.d(getTag(),"null");
    }
  }
.......
}

因此,当我 运行 应用程序从相机拍摄照片,然后转到 Pictures 选项卡时,我将看不到我的照片。我仍然面临同样的问题。

此外,我已经调试了我的代码,它从未进入 updategetItemPostion 方法,这让我最担心。

我一直坚持下去,真的不知道该怎么做。 任何帮助将不胜感激

好的,你可以这样试试:

在您的 MainActivity 中添加此界面:

public interface Updateable {
    public void update();
}

现在,在您的片段中实现此接口并编写代码以在 update 方法内通知适配器:

public class Pictures extends Fragment implements MainActivity.Updateable {
    ...
    @Override
    public void update() {
        if ( adapter != null ) {
            adapter.notifyDataSetChanged();
        } else {
            Log.d(LOG_TAG, "null");
        }
    }
    ...
}

剩下要做的就是在首先加载片段时从 Main Activity 调用 update 方法。您只需在 SectionPagerAdapter 中覆盖 getItemPosition 方法即可,如下所示:

@Override
public int getItemPosition(Object object) {    
    if ( object != null && object instanceof Pictures ) {
        Pictures f = (Pictures) object;

        f.update();
    }
    return super.getItemPosition(object);
}

为了完成工作,最后,您必须调用 viewPager 适配器的 notifyDataSetChanged()。这将强制您的 viewpager 的适配器调用 getItemPosition 方法。

希望这有效!

更新 1

我能想到的另一种方法是以这种方式覆盖 getItemPosition 方法:

@Override
public int getItemPosition(Object object) {    
    return POSITION_NONE;    
}

然后,当您在 MainActivity 中调用 viewPagerAdapter.notifyDataSetChanged() 时,视图分页器将删除所有视图并重新加载它们。也许你可以尝试在保存图片时调用它,或者这样调用:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        int previousState;
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

            if (previousState == ViewPager.SCROLL_STATE_SETTLING && state == ViewPager.SCROLL_STATE_IDLE) {

                if ( viewPagerAdapter.getItem(viewpager.getCurrentItem()) instanceof Pictures ) {
                    Log.d(LOG_TAG, "New Position=" + viewpager.getCurrentItem());

                    viewPagerAdapter.notifyDataSetChanged();
                }

            }
            previousState = state;
        }
    });

希望这有效!