快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

澳门贵宾厅娱乐网址:Android使用ViewPager实现画廊效果的加强版照片墙



记得关于照片墙的文章我已经写过好几篇了,有最基础的照片墙,有瀑布流模式的照片墙,后来又在瀑布流的根基之上加入了查看大年夜图和多点触控缩放的功能。总体来说,照片墙这个Demo在这几篇文章的改进中已经变得较为完善了,本想关于这个功能的系列到此为止,但有同伙跟我反映,感觉在查看大年夜图的时刻最好能经由过程阁下滑动来浏览前后的图片。恩,确凿,似乎对照高真个一些利用都有这样的效果,那么本篇文章中我们来继承对比片墙这个Demo进行改进,让它变得加倍高端大年夜气上档次!

收拾了一下思路,感到自己去实现一套经由过程阁下滑动来切换图片的功能异常不划算,必要编写不少的代码。这里为了要让实现简单化,我们筹备应用Android供给的ViewPager来完成这个功能。

ViewPager的基础用法我就不在本文中先容了,假如还不懂得的同伙可以看http://www.fengfly.com/plus/view-215108-1.html 。

别的,本篇文章的代码是完全在之前文章的根基长进行开拓的,以是假如你还没有看过我前面所写的关于照片墙的文章,建议先去涉猎一下http://www.fengfly.com/plus/view-214550-1.html和 http://www.fengfly.com/plus/view-214551-1.html这两篇文章。

下面就让我们开始着手吧,打开PhotoWallFallsDemo这个项目,首先改动image_details.xml这个结构文件中的代码,如下所示:

xml version="1.0" encoding="utf-8"?>

RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"

android:layout_height="match_parent" >

android.support.v4.view.ViewPagerandroid:id="@+澳门贵宾厅娱乐网址id/view_pager"

android:layout_width="match_parent"android:layout_height="match_parent" >

android.support.v4.view.ViewPager>

TextViewandroid:id="@+id/page_text"

android:layout_width="wrap_content"android:layout_height="wrap_content"

android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"

android:layout_marginBottom="10dp"android:textColor="#fff"

android:textSize="18sp" />

RelativeLayout>

这里我们在结构文件中放置了两个控件,ViewPager和TextView,此中ViewPager自然是用来治理所有的图片的了,而TextView则是用于显示当前图片的页数以及总页数。

然后新建一个zoom_image_layout.xml,在这里放入ZoomImageView控件,如下所示:

xml version="1.0" encoding="utf-8"?>

com.example.photowallfallsdemo.ZoomImageView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/zoom_image_view"

android:layout_width="match_parent"android:layout_height="match_parent"

android:background="#000000" >

com.example.photowallfallsdemo.ZoomImageView>

接下来改动ImageDetailsActivity中的代码,在这里去实现ViewPager的详细功能,代码如下所示:

public class ImageDetailsActivity extends Activity implements OnPageChangeListener {

/**

* 用于治理图片的滑动*/

private ViewPager viewPager;

/奸淫 显示当前图片的页数

*/private TextView pageText;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.image_details);

int imagePosition = getIntent().getIntExtra("image_position", 0);pageText = (TextView) findViewById(R.id.page_text);

viewPager = (ViewPager) findViewById(R.id.view_pager);ViewPagerAdapter adapter = new ViewPagerAdapter();

viewPager.setAdapter(adapte澳门贵宾厅娱乐网址r);viewPager.setCurrentItem(imagePosition);

viewPager.setOnPageChangeListener(this);// 设定当前的页数和总页数

pageText.setText((imagePosition + 1) + "/" + Images.imageUrls.length);}

/**

* ViewPager的适配器*

* @author guolin*/

class ViewPagerAdapter extends PagerAdapter {

@Overridepublic Object instantiateItem(ViewGroup container, int position) {

String imagePath = getImagePath(Images.imageUrls[position]);Bitmap bitmap = BitmapFactory.decodeFile(imagePath);

if (bitmap == null) {bitmap = BitmapFactory.decodeResource(getResources(),

R.drawable.empty_photo);}

View view = LayoutInflater.from(ImageDetailsActivity.this).inflate(R.layout.zoom_image_layout, null);

ZoomImageView zoomImageView = (ZoomImageView) view.findViewById(R.id.zoom_image_view);

zoomImageView.setImageBitmap(bitmap);container.addView(view);

return view;}

@Override

public int getCount() {return Images.imageUrls.length;

}

@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {

return arg0 == arg1;}

@Override

public void destroyItem(ViewGroup container, int position, Object object) {View view = (View) object;

container.removeView(view);}

}

/**

* 获取图片的本地存储路径。*

* @param imageUrl*图片的URL地址。

* @return 图片的本地存储路径。*/

private String getImagePath(String imageUrl) {int lastSlashIndex = imageUrl.lastIndexOf("/");

String imageName = imageUrl.substring(lastSlashIndex + 1);String imageDir = Environment.getExternalStorageDirectory().getPath()

+ "/PhotoWallFalls/";File file = new File(imageDir);

if (!file.exists()) {file.mkdirs();

}String imagePath = imageDir + imageName;

return imagePath;}

@Override

public void onPageScrollStateChanged(int arg0) {

}

@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {

}

@Override

public void onPageSelected(int currentPage) {// 每当页数发生改变时从新设定一遍当前的页数和总页数

pageText.setText((currentPage + 1) + "/" + Images.imageUrls.length);}

}

这个类也是实现滑动切换图片功能最主要的一个类了,因为ViewPager的用法并不繁杂,以是这个类的代码也不多,下面我们来仔细地阐发一下。

首先在onCreate()措施中要去加载我们刚刚改动的image_details.xml结构,然后要从Intent中掏出当前要展示的那张图片的位置。接下来经由过程findViewById()措施获取到ViewPager和TextView控件的实例,并创建了一个ViewPagerAdapter工具作为ViewPager的适配器,之后去调用setCurrentItem()措施来设置当前显示的是哪一张图片。

那么这个ViewPagerAdapter又是什么呢?可以看到,它是一个承袭了PagerAdapter的适配器,是专门用于在ViewPager中应用的。一样平常环境下我们都必要至少去重写PagerAdapter中的instantiateItem()、getCount()、isViewFromObject()和destroyItem()这四个措施。在instantiateItem()措施中,我们根据图片的位置获取到了图片对应的存储路径,然后调用BitmapFactory的解析措施将这张图片解析成一个Bitmap工具,接实在例化zoom_image_layout.xml这个结构,并获取此中的ZoomImageView控件,然后把Bitmap工具设定进去。在getCount()措施,只是简单地返回了一共有若干张图片。isViewFromObject()措施对照简单,便是判断两个参数是否相等就好。而destroyItem()措施中,则是要把应该销毁的View工具收受接收掉落,以防止图片过多导致OOM呈现。

别的,这里的ViewPager澳门贵宾厅娱乐网址还注册了OnPageChangeListener接口,每当ViewPager的页数发明改变时,onPageSelected()措施就会调用。我们在这里让TextView显示当前图片的页数以及总页数即可。

今朝的ImageDetailsActivity已经具备了翻页浏览图片的功能了,假如你心急的话,可以现在就运行试一试。不过一但你运行之后,就会发明,我们还有一些细节事情还没完成。比如说在onCreate()措施中会从Intent中掏出要显示的那张图片的位置,而很显着今朝是取不到了。于是,我们还必要改动MyScrollView中的代码,在这里将点击的那张图片的位置通报过来。因为这个类中的代码异常多,我只列出必要改动的那些部分,如下所示:

public class MyScrollView extends ScrollView implements OnTouchListener {

......

/**

* 开始加载下一页的图片,每张图片都邑开启一个异步线程去下载。*/

public void loadMoreImages() {if (hasSDCard()) {

int startIndex = page * PAGE_SIZE;int endIndex = page * PAGE_SIZE + PAGE_SIZE;

if (startIndexToast.makeText(getContext(), "正在加载...", Toast.LENGTH_SHORT).show();

if (endIndex > Images.imageUrls.length) {endIndex = Images.imageUrls.length;

}for (int i = startIndex; i

LoadImageTask task = new LoadImageTask();taskCollection.add(task);

task.execute(i);}

page++;} else {

Toast.makeText(getContext(), "已没有更多图片", Toast.LENGTH_SHORT).show();}

} else {Toast.makeText(getContext(), "未发明SD卡", Toast.LENGTH_SHORT).show();

}}

/**

* 遍历imageViewList中的每张图片,对图片的可见性进行反省,假如图片已经脱离屏幕可见范围,则将图片调换成一张空图。*/

public void checkVisibility() {for (int i = 0; i

ImageView imageView = imageViewList.get(i);int borderTop = (Integer) imageView.getTag(R.string.border_top);

int borderBottom = (Integer) imageView.getTag(R.string.border_bottom);if (borderBottom > getScrollY() && borderTop

String imageUrl = (String) imageView.getTag(R.string.image_url);Bitmap bitmap = imageLoader.getBitmapFromMemoryCache(imageUrl);

if (bitmap != null) {imageView.setImageBitmap(bitmap);

} else {LoadImageTask task = new LoadImageTask(imageView);

task.execute(i);}

} else {imageView.setImageResource(R.drawable.empty_photo);

}}

}

......

/奸淫 异步下载图片的义务。

** @author guolin

*/class LoadImageTask extends AsyncTask {

/**

* 记录每个图片对应的位置*/

private int mItemPosition;

......

@澳门贵宾厅娱乐网址Overrideprotected Bitmap doInBackground(Integer... params) {

mItemPosition = params[0];mImageUrl = Images.imageUrls[mItemPosition];

Bitmap imageBitmap = imageLoader.getBitmapFromMemoryCache(mImageUrl);if (imageBitmap == null) {

imageBitmap = loadImage(mImageUrl);}

return imageBitmap;}

......

/**

* 向ImageView中添加一张图片*

* @param bitmap*待添加的图片

* @param imageWidth*图片的宽度

* @param imageHeight*图片的高度

*/private void addImage(Bitmap bitmap, int imageWidth, int imageHeight) {

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(imageWidth,imageHeight);

if (mImageView != null) {mImageView.setImageBitmap(bitmap);

} else {ImageView imageView = new ImageView(getContext());

imageView.setLayoutParams(params);imageView.setImageBitmap(bitmap);

imageView.setScaleType(ScaleType.FIT_XY);imageView.setPadding(5, 5, 5, 5);

imageView.setTag(R.string.image_url, mImageUrl);imageView.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

Intent intent = new Intent(getContext(), ImageDetailsActivity.class);intent.putExtra("image_position", mItemPosition);

getContext().startActivity(intent);}

});findColumnToAdd(imageView, imageHeight).addView(imageView);

imageViewLi澳门贵宾厅娱乐网址st.add(imageView);}

}

......

}

}

可以看到,这里我们将LoadImageTask 的泛型进行了改动,doInBackground不再接管一个字符串数组,而是接管一个整型数组,这里传入的参数也就代表着每张图片的位置。这样的话,每个调用LoadImageTask 的地方也都必要进行响应的改动,在loadMoreImages()和checkVisibility()措施中,都将传入的参数改成了图片的位置。着末在addImage()措施中,应用Intent将点击的那张图片对应的位置通报给了ImageDetailsActivity。

今朝看上去统统都完美了吧!但着实还有一点事情我们还没完成。因为ViewPager的事故和ZoomImageView的事故是存在冲突的,以是加入了ViewPager后,ZoomImageView本身的单个手指拖动图片的功能会受很大年夜的影响。以是我们还必要在ZoomImageView的onTouchEvent()中进行判断,假如当前的图片是没有缩放的,则容许经由过程滑动来切换图片,假如当前的图片已经放大年夜了,则要樊篱掉落ViewPager的事故,这样ZoomImageView本身的事故就不会受影响。代码如下所示:

public class ZoomImageView extends View {

......

@Override

public boolean onTouchEvent(MotionEvent event) {if (initRatio == totalRatio) {

getParent().requestDisallowInterceptTouchEvent(false);} else {

getParent().requestDisallowInterceptTouchEvent(true);}

......return true;

}

......

}

这里应用getParent()获取到的便是ViewPager工具,然后调用requestDisallowInterceptTouchEvent()措施来启动和禁用ViewPager的功能。

好了,这样的话,所有的代码就已经完成了,可以运行一下看看完备的效果了。点击随意率性一张图片可以查看大年夜图,然后经由过程阁下滑动可以浏览前后的图片,并且仍旧能够经由过程多点触控对图片进行缩放,效果如下图所示:

除了滑动切换图片之外,在屏幕的底部还能显示当前图片的页数以及总页数,功能已经是相称完善了。今朝这个照片墙Demo的效果已经不亚于市场上一些常见的图片浏览法度榜样了吧。

源码下载,请点击这里

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: