59.仿微信的图片浏览器
涉及知识点:
1.ListView中嵌套GridView
2.AsyncTask异步任务
3.FastJson解析json数据
4.ImageLoader加载图片
5.万能适配器CommonAdapter
6.Fragment的复用和传参
7.PhotoView手势缩放图片
1.自定义的Application,配置ImageLoader
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
DisplayImageOptions defaultOptions = new DisplayImageOptions
.Builder()
.showImageForEmptyUri(R.drawable.empty_photo)
.showImageOnFail(R.drawable.empty_photo)
.cacheInMemory(true)
.cacheOnDisc(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.discCacheSize(50 * 1024 * 1024)//
.discCacheFileCount(100)//缓存一百张图片
.writeDebugLogs()
.build();
ImageLoader.getInstance().init(config);
}
}
2.主界面,异步解析Json,使用万能适配器
public class MainActivity extends Activity {3.图片浏览界面,ViewPager+Fragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
loadData();
}
@InjectView(R.id.lv_content)
ListView lv_content;
@InjectView(R.id.tv_empty)
TextView tv_empty;
private void loadData() {
String jsonStr = FileUtil.getFromAssets(MainActivity.this, "json/data.json");
new ParseJsonTask().execute(jsonStr);
}
class ParseJsonTask extends AsyncTask<String, Integer, MyBean> {
@Override
protected MyBean doInBackground(String... params) {
MyBean myBean = parseJson(params[0]);
return myBean;
}
@Override
protected void onPostExecute(MyBean myBean) {
if (!myBean.getList().isEmpty()) {
showData(myBean);
}
}
private MyBean parseJson(String param) {
return JSON.parseObject(param, MyBean.class);
}
}
private void showData(MyBean myBean) {
tv_empty.setVisibility(View.GONE);
lv_content.setAdapter(new CommonAdapter<MyBean.ListEntity>(
MainActivity.this, myBean.getList(), R.layout.item_friend) {
@Override
public void setItemView(ViewHolder viewHolder, final MyBean.ListEntity item) {
ImageView avator = viewHolder.getView(R.id.avator);
TextView name = viewHolder.getView(R.id.name);
TextView content = viewHolder.getView(R.id.content);
NoScrollGridView gridView = viewHolder.getView(R.id.gridView);
ImageLoader.getInstance().displayImage(item.getAvator(), avator);
name.setText(item.getName());
content.setText(item.getContent());
gridView.setAdapter(new CommonAdapter<String>(
MainActivity.this, item.getUrls(), R.layout.item_thumbnail) {
@Override
public void setItemView(ViewHolder helper, String item) {
ImageView imageView = helper.getView(R.id.album_image);
ImageLoader.getInstance().displayImage(item, imageView);
}
});
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
gotoImagePager(position, item.getUrls());
}
});
}
});
}
private void gotoImagePager(int position, List<String> urls) {
Intent intent = new Intent(this, ImagePagerActivity.class);
intent.putExtra(ImagePagerActivity.EXTRA_IMAGE_INDEX, position);
Bundle args = new Bundle();
args.putSerializable(ImagePagerActivity.EXTRA_IMAGE_URLS, (Serializable) urls);
intent.putExtras(args);
startActivity(intent);
}
}
public class ImagePagerActivity extends FragmentActivity {
private static final String STATE_POSITION = "STATE_POSITION";
public static final String EXTRA_IMAGE_INDEX = "image_index";
public static final String EXTRA_IMAGE_URLS = "image_urls";
private int pagerPosition;
@InjectView(R.id.pager)
HackyViewPager mPager;
@InjectView(R.id.indicator)
TextView indicator;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_detail_pager);
ButterKnife.inject(this);
loadData();
setListener();
}
private void loadData() {
pagerPosition = getIntent().getIntExtra(EXTRA_IMAGE_INDEX, 0);
List<String> urls = (List<String>) getIntent().getSerializableExtra(EXTRA_IMAGE_URLS);
ImagePagerAdapter mAdapter = new ImagePagerAdapter(
getSupportFragmentManager(), urls);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(pagerPosition);
CharSequence text = getString(R.string.viewpager_indicator, 1, mPager
.getAdapter().getCount());
indicator.setText(text);
}
private void setListener() {
// 更新下标
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
CharSequence text = getString(R.string.viewpager_indicator,
arg0 + 1, mPager.getAdapter().getCount());
indicator.setText(text);
}
});
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_POSITION, mPager.getCurrentItem());
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null) {
pagerPosition = savedInstanceState.getInt(STATE_POSITION);
}
}
public class ImagePagerAdapter extends FragmentStatePagerAdapter {
public List<String> mFragmentDatas;
public ImagePagerAdapter(FragmentManager fm, List<String> mFragmentDatas) {
super(fm);
this.mFragmentDatas = mFragmentDatas;
}
@Override
public int getCount() {
return mFragmentDatas == null ? 0 : mFragmentDatas.size();
}
@Override
public Fragment getItem(int position) {
String item = mFragmentDatas.get(position);
return ImageDetailFragment.newInstance(item);
}
}
}
public class ImageDetailFragment extends Fragment {
private String mImageUrl;
private ImageView mImageView;
private ProgressBar progressBar;
private PhotoViewAttacher mAttacher;
public static ImageDetailFragment newInstance(String imageUrl) {
final ImageDetailFragment f = new ImageDetailFragment();
final Bundle args = new Bundle();
args.putString("url", imageUrl);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mImageUrl = getArguments() != null ? getArguments().getString("url") : null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
mImageView = (ImageView) v.findViewById(R.id.image);
mAttacher = new PhotoViewAttacher(mImageView);
mAttacher.setOnPhotoTapListener(new OnPhotoTapListener() {
@Override
public void onPhotoTap(View arg0, float arg1, float arg2) {
getActivity().finish();
}
});
progressBar = (ProgressBar) v.findViewById(R.id.loading);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImageLoader.getInstance().displayImage(mImageUrl, mImageView, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "下载错误";
break;
case DECODING_ERROR:
message = "图片无法显示";
break;
case NETWORK_DENIED:
message = "网络有问题,无法下载";
break;
case OUT_OF_MEMORY:
message = "图片太大无法显示";
break;
case UNKNOWN:
message = "未知的错误";
break;
}
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
progressBar.setVisibility(View.GONE);
mAttacher.update();
}
});
}
}
附1:读取Assets文件
public static String getFromAssets(Context context,String fileName){附2:抛出异常的ViewPager,避免与Fragemnt中的手势冲突
try {
InputStreamReader inputReader = new InputStreamReader( context.getResources().getAssets().open(fileName) );
BufferedReader bufReader = new BufferedReader(inputReader);
String line="";
String Result="";
while((line = bufReader.readLine()) != null)
Result += line;
return Result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public class HackyViewPager extends ViewPager {附3:嵌套在ListView中的GridView,避免只显示首行
private static final String TAG = "HackyViewPager";
public HackyViewPager(Context context) {
super(context);
}
public HackyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
//不理会
Log.e(TAG,"hacky viewpager error1");
return false;
}catch(ArrayIndexOutOfBoundsException e ){
//不理会
Log.e(TAG,"hacky viewpager error2");
return false;
}
}
}
public class NoScrollGridView extends GridView {
public NoScrollGridView(Context context) {
super(context);
}
public NoScrollGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
public class ViewHolder附5:万能的适配器
{
private final SparseArray<View> mViews;
private int mPosition;
private View mConvertView;
private ViewHolder(Context context, ViewGroup parent, int layoutId,
int position)
{
this.mPosition = position;
this.mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
// setTag
mConvertView.setTag(this);
}
/**
* 拿到一个ViewHolder对象
*
* @param context
* @param convertView
* @param parent
* @param layoutId
* @param position
* @return
*/
public static ViewHolder get(Context context, View convertView,
ViewGroup parent, int layoutId, int position)
{
if (convertView == null)
{
return new ViewHolder(context, parent, layoutId, position);
}
return (ViewHolder) convertView.getTag();
}
public View getConvertView()
{
return mConvertView;
}
/**
* 通过控件的Id获取对于的控件,如果没有则加入views
*
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId)
{
View view = mViews.get(viewId);
if (view == null)
{
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
/**
* 为TextView设置字符串
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text)
{
TextView view = getView(viewId);
view.setText(text);
return this;
}
/**
* 为ImageView设置图片
*
* @param viewId
* @param drawableId
* @return
*/
public ViewHolder setImageResource(int viewId, int drawableId)
{
ImageView view = getView(viewId);
view.setImageResource(drawableId);
return this;
}
/**
* 为ImageView设置图片
*
* @param viewId
* @return
*/
public ViewHolder setImageBitmap(int viewId, Bitmap bm)
{
ImageView view = getView(viewId);
view.setImageBitmap(bm);
return this;
}
/**
* 为ImageView设置图片
*
* @param viewId
* @return
*/
public ViewHolder setImageByUrl(int viewId, String url)
{
ImageLoader.getInstance().displayImage(url,
(ImageView) getView(viewId));
return this;
}
public int getPosition()
{
return mPosition;
}
}
public abstract class CommonAdapter<T> extends BaseAdapter
{
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected final int mItemLayoutId;
public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId)
{
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
this.mDatas = mDatas;
this.mItemLayoutId = itemLayoutId;
}
@Override
public int getCount()
{
return mDatas==null?0:mDatas.size();
}
@Override
public T getItem(int position)
{
return mDatas.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
final ViewHolder viewHolder = getViewHolder(position, convertView,
parent);
setItemView(viewHolder, getItem(position));
return viewHolder.getConvertView();
}
public abstract void setItemView(ViewHolder helper, T item);
private ViewHolder getViewHolder(int position, View convertView,
ViewGroup parent)
{
return ViewHolder.get(mContext, convertView, parent, mItemLayoutId,
position);
}
}