在Android ViewPager中设置来自URL的图像

6
我正在按照这个教程实现ViewPager在我的项目中。我已经成功使用静态图片完成了这个过程。现在我想改变它,使得从urls检索图像并在ViewPager中显示。以下是我的代码。

我应该在哪里添加下载图像的方法,如何将其设置到我的ViewPager中?

任何帮助都将不胜感激。

MainActivity:

public class MainActivity extends AppCompatActivity {

    private ArrayList<Integer> images;
    private BitmapFactory.Options options;
    private ViewPager viewPager;
    private View btnNext, btnPrev;
    private FragmentStatePagerAdapter adapter;
    private LinearLayout thumbnailsContainer;
    private final static int[] resourceIDs = new int[]{R.mipmap.a, R.mipmap.b,
            R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f, R.mipmap.g};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        images = new ArrayList<>();

        //find view by id
        viewPager = (ViewPager) findViewById(R.id.view_pager);
        thumbnailsContainer = (LinearLayout) findViewById(R.id.container);
        btnNext = findViewById(R.id.next);
        btnPrev = findViewById(R.id.prev);

        btnPrev.setOnClickListener(onClickListener(0));
        btnNext.setOnClickListener(onClickListener(1));

        setImagesData();

        // init viewpager adapter and attach
        adapter = new ViewPagerAdapter(getSupportFragmentManager(), images);
        viewPager.setAdapter(adapter);

        inflateThumbnails();
    }

    private View.OnClickListener onClickListener(final int i) {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (i > 0) {
                    //next page
                    if (viewPager.getCurrentItem() < viewPager.getAdapter().getCount() - 1) {
                        viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
                    }
                } else {
                    //previous page
                    if (viewPager.getCurrentItem() > 0) {
                        viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
                    }
                }
            }
        };
    }

    private void setImagesData() {
        for (int i = 0; i < resourceIDs.length; i++) {
            images.add(resourceIDs[i]);
        }
    }

    private void inflateThumbnails() {
        for (int i = 0; i < images.size(); i++) {
            View imageLayout = getLayoutInflater().inflate(R.layout.item_image, null);
            ImageView imageView = (ImageView) imageLayout.findViewById(R.id.img_thumb);
            imageView.setOnClickListener(onChagePageClickListener(i));
            options = new BitmapFactory.Options();
            options.inSampleSize = 3;
            options.inDither = false;
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), images.get(i), options );
            imageView.setImageBitmap(bitmap);
            //set to image view
            imageView.setImageBitmap(bitmap);
            //add imageview
            thumbnailsContainer.addView(imageLayout);
        }
    }

    private View.OnClickListener onChagePageClickListener(final int i) {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager.setCurrentItem(i);
            }
        };
    }
}

PageFragment类:

   public class PageFragment extends Fragment {

        private int imageResource;
        private Bitmap bitmap;

        public static PageFragment getInstance(int resourceID) {
            PageFragment f = new PageFragment();
            Bundle args = new Bundle();
            args.putInt("image_source", resourceID);
            f.setArguments(args);
            return f;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            imageResource = getArguments().getInt("image_source");
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_page, container, false);
        }

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            ImageView imageView = (ImageView) view.findViewById(R.id.image);

            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inSampleSize = 4;
            o.inDither = false;
            bitmap = BitmapFactory.decodeResource(getResources(), imageResource, o);
            imageView.setImageBitmap(bitmap);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            bitmap.recycle();
            bitmap = null;
        }
    }

ViewPager Adapter class:

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    private List<Integer> images;

    public ViewPagerAdapter(FragmentManager fm, List<Integer> imagesList) {
        super(fm);
        this.images = imagesList;
    }

    @Override
    public Fragment getItem(int position) {
        return PageFragment.getInstance(images.get(position));
    }

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

你想从URL下载图像吗? - Chirag Savsani
是的,我有一个图像URL数组。我的意思是我想从这些URL设置图像,而不是下载。 - Jas
@Jas,你的意思是想从那些获取不到图片的URL中设置默认图片吗? - dex
不,我得到的教程是用于显示来自我的可绘制文件夹的图像。现在我想将其更改为从URL下载的图像。 - Jas
我能否简单地使用AsyncTask并将位图传递给我的ViewPager? - Jas
2
为什么要重复造轮子呢?可以使用以下图片加载库:Universal Image LoaderPicassoGlide - shreyash mashru
7个回答

15

要在图片中使用ViewPager,您需要创建一个适配器,该适配器扩展了像下面这样的PagerAdapter

public class ImagePagerAdapter extends PagerAdapter {

    Context context;
    LayoutInflater layoutInflater;

    ArrayList<String> arrayList;

    public ImagePagerAdapter(Context context, ArrayList<String> arrayList) {
        this.context = context;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.arrayList = arrayList;
    }

    @Override
    public int getCount() {
        if(arrayList != null){
            return arrayList.size();
        }
        return 0;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((LinearLayout) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View itemView = layoutInflater.inflate(R.layout.image_viewpager_layout, container, false);

        ImageView imageView = (ImageView) itemView.findViewById(R.id.viewPagerItem_image1);

        Picasso.with(context).load(arrayList.get(position))
                            .placeholder(R.drawable.image_uploading)
                            .error(R.drawable.image_not_found).into(imageView);

        container.addView(itemView);

        return itemView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((LinearLayout) object);
    }

}

适配器使用的XML布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


        <ImageView
            android:id="@+id/viewPagerItem_image1"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:scaleType="fitXY"
            android:src="@drawable/ic_launcher"/>


</LinearLayout>

2

要从 URL 下载图像,您需要使用 AsyncTask

为此,请按照以下 DownloadImageFromAsyncTask 示例。

new LoadImage().execute("http://www.sumtrix.com/images/sumtrix/Android-Wallpaper-HD.jpg");

将您的url设置为上面的url。

private class LoadImage extends AsyncTask<String, String, Bitmap> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setMessage("Loading Image...");
            dialog.show();

        }

        @Override
        protected Bitmap doInBackground(String... params) {

            try {
                bitmap = BitmapFactory.decodeStream((InputStream) new URL(params[0]).getContent());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null) {
                img.setImageBitmap(result);
                dialog.dismiss();
            } else {
                dialog.dismiss();
                Toast.makeText(getApplicationContext(), "Image Does Not Exist...",
                        Toast.LENGTH_LONG).show();
            }

        }

    }

为此,您需要在AndroidManifest.xml文件中添加权限。
<uses-permission android:name="android.permission.INTERNET" />

请检查我的类并根据我的要求提供答案。 - Jas
谢谢你的回答。我使用了Picasso来简化它。 - Jas

1

我认为你应该在这里设置你的图片,你的imageResource就是你的imgUrl,可以使用一些库来支持加载图片,比如:UniversalImageLoaderVolleyPicasso等等,我们有很多库来支持通过url加载图片。

 @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ImageView imageView = (ImageView) view.findViewById(R.id.image);

        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inSampleSize = 4;
        o.inDither = false;
        bitmap = BitmapFactory.decodeResource(getResources(), imageResource, o);
        imageView.setImageBitmap(bitmap);
    }

谢谢你的回答。我使用了Picasso来简化它。 - Jas

1
使用此代码下载并显示在imageView上。
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout_here);
        new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
            .execute("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png");
    }

    public void onClick(View v) {
        startActivity(new Intent(this, IndexActivity.class));
        finish();
    }

    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap mIcon11 = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon11 = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return mIcon11;
        }

        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }
}

在AndroidManifest.xml文件中添加Internet权限。
<uses-permission android:name="android.permission.INTERNET" />

请参阅此链接以获取更多详细信息。

请检查我的类并根据我的要求提供答案,谢谢。 - Jas
1
@Jas,我们不会在这里为您编写代码,我们将指导您如何完成一个特定的任务,您必须理解并根据自己的要求实现。为了在ImageView中使用URL,首先您需要创建一个图像URL的ArrayList,将其传递给上面的异步任务,并与相应的ImageView一起使用,它将首先下载图像,然后自动显示在ImageView上。希望能对您有所帮助。 - Amitabh Sarkar
1
谢谢你的回答。我使用了Picasso来简化它。 - Jas

1

当我需要从URL显示图像时,我使用Picasso库。它非常简单易用。

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ImageView imageView = (ImageView) view.findViewById(R.id.image);

    Picasso.with(this)
        .load(image_url)
        .into(imageView);
}

你可以从这里查看参考资料并下载库文件,Picasso
希望对你有所帮助。

1

你应该在onViewCreated()中调用picdownloadertask。

    @Override
            public void onViewCreated(View view, Bundle savedInstanceState) {
                super.onViewCreated(view, savedInstanceState);
                ImageView imageView = (ImageView) view.findViewById(R.id.image);
               new PicDownladerTask().execute(url)


            }

类PicDownloaderTask继承自AsyncTask {

        @Override
        protected Bitmap doInBackground(String... strings) {
            Bitmap bitmap = getBitmap(strings[0]);
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
               BitmapFactory.Options o = new BitmapFactory.Options();
            o.inSampleSize = 4;
            o.inDither = false;
            bitmap = BitmapFactory.decodeResource(getResources(), imageResource, o);
            imageView.setImageBitmap(bitmap);
        }

这是从URL获取图片的方法

 public static Bitmap getBitmap(String url)
    {
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);

            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(70000);
            conn.setReadTimeout(70000);

            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
//            OutputStream os = new FileOutputStream(f);
//            Utils.CopyStream(is, os);
//            os.close();
            bitmap = BitmapFactory.decodeStream(is);
            conn.disconnect();
//            bitmap = decodeFile(f);
            return bitmap;
        } catch (Throwable ex){
            ex.printStackTrace();
            if(ex instanceof OutOfMemoryError){}
//                memoryCache.clear();
            return null;
        }
    }

1
@Jas 为了让事情变得更简单,你总是使用像(okhttp和picasso)或(ion)这样的库,这些库已经被开发人员广泛接受。然后,下载和显示图像的过程就可以用一行代码完成。 - shreyas
谢谢回答。我使用了 Picasso 来简化。 - Jas
@Jas,那肯定会减少工作量。由于问题已经解决,几乎所有答案都是正确的。选择一个并关闭问题。 - shreyas

1
创建一个异步任务,在后台执行下载图片的操作。
@Override
    protected Bitmap doInBackground(String... url) {
        this.url = url[0];
        final DefaultHttpClient client = new DefaultHttpClient();
        final org.apache.http.client.methods.HttpGet getRequest = new org.apache.http.client.methods.HttpGet(
                url[0]);

        try {
            HttpResponse response = client.execute(getRequest);
            final int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode != HttpStatus.SC_OK) {
                LoggerUtils.logWarn("ImageDownloader", "Error "
                        + statusCode + " while retrieving bitmap from "
                        + url[0]);
                return null;
            }
            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream inputStream = null;
                try {
                    inputStream = entity.getContent();

                    final Bitmap bitmap = BitmapFactory
                            .decodeStream(inputStream);
                    return bitmap;
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
        } catch (Exception e) {
            getRequest.abort();

        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接