这是一个图库应用程序示例,其中我从服务器检索图像并使用Glide在ViewPager上显示它,并且ViewPager上还具有共享和下载功能。当我缓慢滑动图像时,一切工作都很好,但是当我连续快速滑动图像时,尝试共享和下载图像时,图像位置错误。需要一些建议来解决此问题。谢谢。
活动:
public class SlideActivity extends AppCompatActivity {
private static final String URL = "API";
private ViewPager viewPager;
private Context context = SlideActivity.this;
private ViewPagerAdapter adapter;
private int position;
private List<Trending> data;
private ImageView shareIcon, shareImage, downloadImage;
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slide_activity);
viewPager = findViewById(R.id.viewPager);
final ProgressBar progressBar = findViewById(R.id.progress);
shareIcon = findViewById(R.id.shareviewpager);
downloadImage = findViewById(R.id.iv_download_slide);
//final String fileName = getIntent().getStringExtra("filename");
position = getIntent().getIntExtra("pos", 0);
progressBar.setVisibility(View.VISIBLE);
StringRequest request = new StringRequest(URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
TrendingData users = gson.fromJson(response, SlideData.class);
data = users.getData();
adapter = new ViewPagerAdapter(context, data);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);
viewPager.setCurrentItem(position);
if (position == 0) {
pageSelected(0);
}
progressBar.setVisibility(View.INVISIBLE);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.INVISIBLE);
Toast.makeText(SlideActivity.this, "Oops Something Went Wrong. Please try again later..", Toast.LENGTH_SHORT).show();
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
pageSelected(i);
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
}
//separate Thread for sharing Images
private static class LoadImage extends AsyncTask<String, Integer, Drawable> {
private WeakReference<TrendingSlideActivity> activityWeakReference;
LoadImage(SlideActivity context) {
activityWeakReference = new WeakReference<>(context);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Drawable doInBackground(String... strings) {
Bitmap bmp = null;
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(strings[0]).openConnection();
connection.connect();
InputStream input = new BufferedInputStream(connection.getInputStream());
//bmp = BitmapFactory.decodeStream(input);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
options.outHeight = 50;
options.outWidth = 50;
String imageType = options.outMimeType;
options.inSampleSize = 4;
//options.inPreferredConfig = Bitmap.Config.RGB_565;
bmp = BitmapFactory.decodeStream(input, null, options);
} catch (IOException e) {
e.printStackTrace();
}finally {
assert connection != null;
connection.disconnect();
}
return new BitmapDrawable(bmp);
}
@Override
protected void onPostExecute(Drawable result) {
SlideActivity activity = activityWeakReference.get();
if (activity == null) return;
activity.shareImage = new ImageView(activity);
//Add image to ImageView
activity.shareImage.setImageDrawable(result);
}
}
//share function
public void onShareItem(View v) {
// Get access to bitmap image from view
// Get access to the URI for the bitmap
if (v != null) {
Uri bmpUri = getLocalBitmapUri((ImageView) v);
if (bmpUri != null) {
// Construct a ShareIntent with link to image
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/*");
// Launch sharing dialog for image
context.startActivity(Intent.createChooser(shareIntent, "Share Data"));
} else {
// ...sharing failed, handle error
}
}else {
Toast.makeText(SlideActivity.this,"Please Wait Image is Loading...",Toast.LENGTH_SHORT).show();
}
}
//converting imageView into Bitmap
public Uri getLocalBitmapUri(ImageView imageView) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageView.getDrawable();
Bitmap bmp;
if (drawable instanceof BitmapDrawable) {
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
} else {
return null;
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
// Use methods on Context to access package-specific directories on external storage.
// This way, you don't need to request external read/write permission.
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
// **Warning:** This will fail for API >= 24, use a FileProvider as shown below instead.
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
//checking storage permission
public boolean isStoragePermissionGranted() {
String TAG = "Storage Permission";
if (Build.VERSION.SDK_INT >= 23) {
if (this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission is granted");
return true;
} else {
Log.i(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.i(TAG, "Permission is granted");
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
AlertDialog alertDialog =
new AlertDialog.Builder(SlideActivity.this)
.setTitle("Required Storage Permission")
.setMessage("You have disabled the permission permanently,\n" +
"To enable the permissions press Yes you will be navigated to Settings screen")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Action for 'NO' Button
dialog.cancel();
Toast.makeText(getApplicationContext(),"This Permission is Required to Download & Share Images.",
Toast.LENGTH_SHORT).show();
}
}).show();
alertDialog.setCanceledOnTouchOutside(true);
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
//Saving Image to SD Card
public void saveImageToGallery(ImageView iv) {
// //to get the image from the ImageView (say iv)
// BitmapDrawable draw = (BitmapDrawable) iv.getDrawable();
// Bitmap bitmap = draw.getBitmap();
if (iv != null) {
Drawable drawable = iv.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable) {
bmp = ((BitmapDrawable) iv.getDrawable()).getBitmap();
} else {
}
FileOutputStream outStream = null;
String sdCard = Environment.getExternalStorageDirectory().toString();
if (isStoragePermissionGranted()) {
File dir = new File(sdCard, "/GalleryApp");
if (!dir.exists()) {
boolean mkdirs = dir.mkdirs();
}
try {
String fileName = String.format(Locale.getDefault(),"%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
outStream = new FileOutputStream(outFile);
assert bmp != null;
bmp.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
Toast.makeText(SlideActivity.this, "Image Saved", Toast.LENGTH_SHORT).show();
Log.i("TAAAAAAAAAAAAG", "onPictureTaken - wrote to " + outFile.getAbsolutePath());
String filePath = outFile.getPath();
MediaScannerConnection.scanFile(this,
new String[]{filePath}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
Toast.makeText(SlideActivity.this, "Please Wait Image is Loading...", Toast.LENGTH_SHORT).show();
}
}
public void pageSelected(int position) {
//currentImage = viewPager.getCurrentItem();
//Log.i("TAG", "page selected " + currentImage);
final String fileName1 = data.get(position).getFileName();
final String url2 = "API" + fileName1;
new LoadImage(TrendingSlideActivity.this).execute(url2);
shareIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isStoragePermissionGranted()) {
onShareItem(shareImage);
}
}
});
downloadImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
saveImageToGallery(shareImage);
}
});
}
}
ViewPagerAdapter
public class ViewPagerAdapter extends PagerAdapter {
private static final String URL = "API";
private Context context;
private LayoutInflater inflater;
private ImageView wallpaper;
private List<Trending> data;
View view;
String url;
ViewPager viewPager;
public ViewPagerAdapter() {
}
public ViewPagerAdapter(Context context, List<Trending> data) {
this.context = context;
this.data = data;
}
@SuppressLint("ClickableViewAccessibility")
@NonNull
@Override
public Object instantiateItem(@NonNull final ViewGroup container,int position) {
inflater = LayoutInflater.from(container.getContext());
final View view = inflater.inflate(R.layout.trending_viewpager_item_layout, container, false);
viewPager = view.findViewById(R.id.viewPager);
wallpaper = view.findViewById(R.id.walpaperImage);
final String fileName1 = data.get(position).getFileName();
//final String id = data.get(position).getId();
url = URL + fileName1;
Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.ALL).into(wallpaper);
container.addView(view,0);
return view;
}
@Override
public int getCount() {
return data.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view.equals(o);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
}