Android中利用PhotoView查看图片

来源:互联网 发布:剑三病娇花萝捏脸数据 编辑:程序博客网 时间:2024/06/05 21:00

思路:当我们响应一个点击事件的时候 ,弹出一个dialog,我们将这个dialog自定义为全屏背景为半透明,这样图片以外的地方就会变成半透明,达到了查看图片的效果。

好了,首先我们必须要做的一件事情就是在build.gradle中导入相应的依赖,否则有些类是无法使用的。

dependencies {    compile 'com.github.bumptech.glide:glide:3.7.0'    compile 'com.github.chrisbanes.photoview:library:+'    compile 'com.android.support:appcompat-v7:25.3.1'    compile 'com.android.support.constraint:constraint-layout:1.0.2'}

然后我们在values文件夹中的styles.xml文件中自定义一个dialog。

<style name="transparentBgDialog" parent="@android:style/Theme.Dialog">        <item name="android:windowFrame">@null</item>        <item name="android:windowIsFloating">true</item>        <item name="android:windowIsTranslucent">true</item>        <item name="android:windowBackground">@color/transparent</item>        <item name="android:backgroundDimEnabled">true</item>        <item name="android:background">@color/transparent</item>        <item name="android:windowNoTitle">true</item>    </style>

接着我们需要写一个给显示dialog的布局文件,我们命名为dialog_images_brower.xml,但是在此之前,我们需要重写ViewPager控件,因为ViewPager存在一个闪退的bug,我们将我们重写的控件命名为ShowImagesViewPager.java。

public class ShowImagesViewPager extends ViewPager {    public ShowImagesViewPager(Context context) {        this(context,null);    }    public ShowImagesViewPager(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        try {            return super.onInterceptTouchEvent(ev);        } catch (IllegalArgumentException e) {            return false;        }    }}

然后我们就可以开始写布局文件dialog_images_brower.xml了。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:gravity="center_horizontal"             android:orientation="vertical"             android:paddingTop="@dimen/padding_small_5dp">    <com.damon43.showimagesdialogdemo.component.ShowImagesViewPager        android:id="@+id/vp_images"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:paddingTop="@dimen/padding_small_10dp"/></FrameLayout>

当我们写好了布局文件后,我们需要使用它,那么我们就需要自己重写一个dialog类文件,我们创建ShowImagesDialog继承自Dialog,并且为ViewPager写一个适配器ShowImagesAdapter继承自PagerAdapter,将我们需要查看的图片适配进去。

public class ShowImagesDialog extends Dialog {    private View mView ;    private Context mContext;    private ShowImagesViewPager mViewPager;    private List<String> mImgUrls;    private List<View> mViews;    private ShowImagesAdapter mAdapter;    public ShowImagesDialog(@NonNull Context context, List<String> imgUrls) {        super(context, R.style.transparentBgDialog);        this.mContext = context;//传入上下文        this.mImgUrls = imgUrls;//传入图片String数组        initView();        initData();    }    private void initView() {        mView = View.inflate(mContext, R.layout.dialog_images_brower, null);//通过inflate()方法找到我们写好的包含ViewPager的布局文件        mViewPager = (ShowImagesViewPager) mView.findViewById(R.id.vp_images);//找到ViewPager控件并且实例化        mViews = new ArrayList<>();//创建一个控件的数组,我们可以在ViewPager中加入很多图片,滑动改变图片    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(mView);        Window window = getWindow();        WindowManager.LayoutParams wl = window.getAttributes();        wl.x = 0;        wl.y = 0;        wl.height = Config.EXACT_SCREEN_HEIGHT;        wl.width = Config.EXACT_SCREEN_WIDTH;        wl.gravity = Gravity.CENTER;        window.setAttributes(wl);        //EXACT_SCREEN_HEIGHT,EXACT_SCREEN_WIDTH为自定义Config类中的静态变量        //在MainActivity中会给这两个变量赋值,分别对应手机屏幕高度和宽度        //在这里我们通过WindowManager.LayoutParams把当前dialog的大小设置为全屏    }    private void initData() {        //当PhotoView被点击时,添加相应的点击事件        PhotoViewAttacher.OnPhotoTapListener listener = new PhotoViewAttacher.OnPhotoTapListener() {            @Override            public void onPhotoTap(View view, float x, float y) {                dismiss();//点击图片后,返回到原来的界面            }        };        for (int i = 0; i < mImgUrls.size(); i++) {            final PhotoView photoView = new uk.co.senab.photoview.PhotoView(mContext);            //创建一个PhotoView对象            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);            photoView.setLayoutParams(layoutParams);            //我们通过ViewGroup.LayoutParams来设置子控件PhotoView的大小            photoView.setOnPhotoTapListener(listener);//给PhotoView添加点击事件            Glide.with(mContext)                    .load(mImgUrls.get(i))//导入图片                    .placeholder(R.mipmap.ic_launcher)//加载图片过程中显示的替代图片                    .error(R.mipmap.ic_launcher)//图片加载失败时显示的图片                    .into(new SimpleTarget<GlideDrawable>() {                        //这是Glide的一个回调方法                        //我们首先定义了一个SimpleTarget,然后把它通过into方法传入。                        // 这样当Glide去服务器请求图片成功之后,                        // 它会把请求到的图片资源作为GlideDrawable传递回来,                        // 你可以使用这个GlideDrawable进行自己想要的操作,                @Override                public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {                    photoView.setImageDrawable(resource);                    //我们把回调过来的图片资源加载到PhotoView中                    //大家有没有发现一个细节,我在布局文件中并没有创建PhotoView控件,而是创建的ViewPager                    //因为我们需要在ViewPager中加入多个PhotoView以达到图片翻页的功能                    //因此我们在加载图片时,想要把图片加载到任意的图片控件中,就需要Glide回调方法                }            });            mViews.add(photoView);//最后把我们加载的所有PhotoView传给View数组        }        mAdapter = new ShowImagesAdapter(mViews);//给适配器传入图片控件数组        mViewPager.setAdapter(mAdapter);        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {            //给ViewPager添加监听事件            @Override            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {            }            @Override            public void onPageSelected(int position) {            }            @Override            public void onPageScrollStateChanged(int state) {            }        });    }}

然后贴入我的适配器代码

public class ShowImagesAdapter extends PagerAdapter {    private List<View> views;    public ShowImagesAdapter(List<View> views) {        this.views = views;    }    @Override    public boolean isViewFromObject(View arg0, Object arg1) {        return arg0 == arg1;        //确定一个页面视图是否关联到一个特定的对象。    }    @Override    public int getCount() {        return views.size();        //得到控件数组个数    }    //一般来说,destroyitem在viewpager移除一个item时调用。    // viewpage一般都会缓冲3个item,即一开始就会调用3次instantiateItem,    // 当向右滑动,到第3页时,第1页的item会被调用到destroyitem    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        ((ViewPager) container).removeView(views.get(position));    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        ((ViewPager) container).addView(views.get(position));        return views.get(position);    }}

好了,我们把自定义的dialog搞定了,接下来我们可以直接在MainActivity中使用了。由于我们封装性很强,因此使用方法很简单,直接new一个ShowImagesDialog类就行了~

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        getDeviceDensity();        final List<String> urls = new ArrayList<>();        urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1511198824138&di=cec97b6363a1bce28b8499a31b78df83&imgtype=0&src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farchive%2F3e282f8762696b0bbb3ed16a5dc193c718e5aff9.jpg");        urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1511793592&di=08b8de22336028a68c9a0bbbe7a9066d&imgtype=jpg&er=1&src=http%3A%2F%2Fi1.hdslb.com%2Fbfs%2Farchive%2F7ea7878cfbddb27bb8a23e2407bfa7a48655f317.jpg");        urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1511198824136&di=f4dc71ffdbbb16d9e3d496cf8add5376&imgtype=0&src=http%3A%2F%2Foss.tan8.com%2Fresource%2Fattachment%2F2017%2F201707%2F962b7304d0adc7e2e1d374dc6786e302.jpg");        findViewById(R.id.btn_show_imgs).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new ShowImagesDialog(MainActivity.this, urls).show();            }        });    }    /**     * 获取当前设备的屏幕密度等基本参数     */    protected void getDeviceDensity() {        DisplayMetrics metrics = new DisplayMetrics();//通过DisplayMetrics类可以得到手机屏幕的参数        getWindowManager().getDefaultDisplay().getMetrics(metrics);//然后将DisplayMetrics对象传入        Config.EXACT_SCREEN_HEIGHT = metrics.heightPixels;//得到手机屏幕的高的分辨率        Config.EXACT_SCREEN_WIDTH = metrics.widthPixels;//得到手机屏幕宽的分辨率    }}

这是MainActivity的布局

<FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:padding="@dimen/padding_small_10dp"    android:layout_height="match_parent">    <Button        android:id="@+id/btn_show_imgs"        android:layout_gravity="center_horizontal"        android:layout_marginTop="@dimen/padding_small_10dp"        android:text="@string/clicktoshowimgs"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></FrameLayout>

是不是很简单,我们直接点击一个按钮,就可以查看我们从网络上获取的图片了。

这里写图片描述
这里写图片描述
这里写图片描述

原创粉丝点击