涉及知识点:
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 { @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 AsyncTask3.图片浏览界面,ViewPager+Fragment{ @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 ( 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 ( 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 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); Listurls = (List ) 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 mFragmentDatas; public ImagePagerAdapter(FragmentManager fm, List 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){ 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; }附2:抛出异常的ViewPager,避免与Fragemnt中的手势冲突
public class HackyViewPager extends ViewPager { 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; } } }附3:嵌套在ListView中的GridView,避免只显示首行
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 { private final SparseArray附5:万能的适配器mViews; private int mPosition; private View mConvertView; private ViewHolder(Context context, ViewGroup parent, int layoutId, int position) { this.mPosition = position; this.mViews = new SparseArray (); 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 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 CommonAdapterextends BaseAdapter { protected LayoutInflater mInflater; protected Context mContext; protected List mDatas; protected final int mItemLayoutId; public CommonAdapter(Context context, List 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); } }