Android如何在标签更改/滑动时刷新图像网格视图适配器?

时间:2017-02-02 13:57:36

标签: android image android-studio tabs baseadapter

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

enter image description here

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

以下是我的适配器代码

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方法,这让我最担心。

我坚持认真,并不知道如何做到这一点。 任何帮助都将受到高度赞赏

1 个答案:

答案 0 :(得分:2)

好的,你可以这样试试:

在您的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");
        }
    }
    ...
}

当片段首先加载时,剩下要做的是从主活动调用update方法。您只需在getItemPosition中覆盖SectionPagerAdapter方法就可以执行此操作,如下所示:

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

希望这有效!