Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)
2013-06-03 20:22
711 查看
解析服务端JSON的内容和图片,通过异步任务下载并设置到listview页上,点击listview跳转到详情页。
其他优化和扩展:
1.图片加载 与设置图片方法一样,将控件对象传到异步任务里
2.惰性加载
其他相关:
1.隐藏headview
public class WatchingActivity extends Activity implements OnClickListener, OnItemClickListener { private ListView mListView; private HashMap<URL, Bitmap> mCacheMap = new HashMap<URL, Bitmap>(); private View errorView; private View loadingview; private RelativeLayout errorlayout; private Button btn_netRetry; private View headview; private View footview; private View btn_footviewloading; private TextView btn_loadmore; private int mPage = 1; private BaseAdapter mAdapter; private ArrayList<ItemData> mDataList = new ArrayList<ItemData>(); private View headviewad; private View imageBtn_refresh; /* * 创建布局 * 下载内容 * 解析内容 * 下载图片 * 图片缓存 * 网络错误页面 * 网络加载页面 * 增加页眉 * 加载更多 * 页眉响应 * ListView行跳转 * 内容页显示详情 */ /** * 1.适配器判断是否为空,生命周期?还是因为是第一次===========> 复用会导致数据重新刷新,不能在原有数据基础上加载 * 2.页眉整张图片,则无法直接点击------------------->layout拦截掉了监听 * 3.加载更多链接不在时result会报错空值---------------> * 4.mListView.setOnItemClickListener(this);用这个方法监听ListView无效?========>监听行布局对象 * 5.顶部刷新按钮为何不响应? * 6.行布局的进度条为何找不到?========>已解决 * 7.include移位就报错==============>没问题 * 8.控件层次如何改变=============> relative根据xml代码位置 * 9.setonItemClick position要减1才能对应?============> 加完headview后,position初始值自动加1 * */ class ItemData { String imageUrl; String title; String from; String time; String content; public ItemData(String imageUrl, String title, String from, String time, String content) { super(); this.imageUrl = imageUrl; this.title = title; this.from = from; this.time = time; this.content = content; } } class ViewHolder { ImageView imageView; TextView textView_title; TextView textView_from; TextView textView_time; ProgressBar progressBar_imageLoading; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_watching); setUI(); } private void setUI() { LayoutInflater inflater = getLayoutInflater(); headview = inflater.inflate(R.layout.headview, null); footview = inflater.inflate(R.layout.footview, null); btn_footviewloading = footview.findViewById(R.id.footview_loading); btn_loadmore = (TextView) footview.findViewById(R.id.btn_loadmore); headviewad = headview.findViewById(R.id.imageView_headview_ad); imageBtn_refresh = findViewById(R.id.imageBtn_refresh); btn_netRetry = (Button) findViewById(R.id.btn_netRetry); loadingview = findViewById(R.id.loadingview); errorView = findViewById(R.id.errorview); mListView = (ListView) findViewById(R.id.listView_watching); mListView.addHeaderView(headview);//注意:一定要在setAdapter之前调用,所以一般在找到listview之后就添加 mListView.addFooterView(footview); loadTask(); //网络连接重试按钮 btn_netRetry.setOnClickListener(this); //分页加载更多 btn_loadmore.setOnClickListener(this); //点击ListView页眉广告 headviewad.setOnClickListener(this); //点击顶部刷新页面 btn_netRetry.setOnClickListener(this); //点击listview跳转 mListView.setOnItemClickListener(this); } //按钮点击事件 @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_netRetry: errorView.setVisibility(View.GONE); mPage = 1; loadTask(); break; case R.id.btn_loadmore: btn_loadmore.setVisibility(View.INVISIBLE); btn_footviewloading.setVisibility(View.VISIBLE); loadTask(); break; case R.id.imageView_headview_ad: Toast.makeText(WatchingActivity.this, Contant.HEADVIEW_TOAST, Toast.LENGTH_LONG).show(); break; case R.id.imageBtn_refresh: loadTask(); break; default: break; } } //监听listview @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(view.getId() == R.id.watching_item)//监听的对象是行布局 { Intent intent = new Intent(WatchingActivity.this, ContentActivity.class); ItemData data = mDataList.get(position - 1); String fromtime = data.from +" " + Contant.TIME_YEAR + data.time; intent.putExtra(Contant.KEY_INTENTER_TITLE, data.title); intent.putExtra(Contant.KEY_INTENTER_FROMTIME, fromtime); intent.putExtra(Contant.KEY_INTENTER_CONTENT, data.content); startActivity(intent); } } //启动异步任务 private void loadTask() { URL dataUrl = null; try { dataUrl = new URL(Contant.URL_DATA + mPage + Contant.URL_DATA_FILEFORM); // 异步任务下载数据 LoadDataTask loadDataTask = new LoadDataTask(); loadDataTask.execute(dataUrl); } catch (MalformedURLException e) { e.printStackTrace(); } } // 异步任务下载数据 class LoadDataTask extends AsyncTask<URL, Void, String> { @Override protected void onPreExecute() { loadingview.setVisibility(View.VISIBLE); } @Override protected String doInURL... params) { InputStream is = null; ByteArrayBuffer strBuf = new ByteArrayBuffer(59658);//使用ByteArrayBuffer,直接使用String可能造成读取到的部分内容乱码 try { HttpURLConnection conn = (HttpURLConnection) params[0].openConnection(); conn.setConnectTimeout(Contant.HTTP_TIME_OUT); conn.setReadTimeout(Contant.HTTP_TIME_OUT); // 判断网络连接是否正常 if(conn.getResponseCode() != HttpURLConnection.HTTP_OK) { //返回错误提示页面 return null; } // 下载数据 is = conn.getInputStream(); byte[] buf = new byte[1024]; int len = 0; while (-1 != (len = is.read(buf))) { strBuf.append(buf, 0, len);//直接加入ByteArrayBuffer } } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return new String(strBuf.buffer());//bytebuffer数组转成字符串 } // 下载数据解析,更新控件内容 @Override protected void onPostExecute(String result) { loadingview.setVisibility(View.GONE); //判断result是否为空 if(TextUtils.isEmpty(result.trim())) { btn_loadmore.setVisibility(View.GONE); errorView.setVisibility(View.VISIBLE); mListView.setVisibility(View.GONE); // return; } else { btn_loadmore.setVisibility(View.VISIBLE); btn_footviewloading.setVisibility(View.INVISIBLE); mListView.setVisibility(View.VISIBLE); // 解析json数据 ArrayList<ItemData> dataList = parse(result); //更新控件内容 setListData(dataList); } } } //更新行内容 private void setListData(ArrayList<ItemData> dataList) { //判断mAdapter是否为空,复用mAdapter实现内容加载,重新set会导致所有内容重新加载(跳到第一行) if(null == mAdapter) { createAdapter(dataList);//创建适配器 mListView.setAdapter(mAdapter); } else { mAdapter.notifyDataSetChanged();//通知listview更新界面 } } // 解析json数据 private ArrayList<ItemData> parse(String result) { try { JSONArray jsonArray = new JSONArray(result); mPage++;//数据解析完成后,页数修改 for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String imageUrl = Contant.URL_HOST + jsonObject.getString(Contant.KEY_JSON_IMGURL); String title = jsonObject.getString(Contant.KEY_JSON_TITLE); String from = jsonObject.getString(Contant.KEY_JSON_FROM); String time = jsonObject.getString(Contant.KEY_JSON_TIME); String content = jsonObject.getString(Contant.KEY_JSON_CONTENT); ItemData itemData = new ItemData(imageUrl, title, from, time,content); mDataList.add(itemData); } } catch (JSONException e) { e.printStackTrace(); } return mDataList; } //创建Adapter,设置LiseView private void createAdapter(final ArrayList<ItemData> dataList) { mAdapter = new BaseAdapter() { @Override public View getView(int position, View convertView,ViewGroup parent) { ViewHolder holder; if(convertView == null) { LayoutInflater inflater = getLayoutInflater(); convertView = inflater.inflate(R.layout.watch_layout, null); holder = new ViewHolder(); holder.imageView = (ImageView) convertView.findViewById(R.id.imgView_watch_newspic); holder.textView_title = (TextView) convertView.findViewById(R.id.txtView_watch_title); holder.textView_from = (TextView) convertView.findViewById(R.id.txtView_from); holder.textView_time = (TextView) convertView.findViewById(R.id.txtView_time); holder.progressBar_imageLoading = (ProgressBar) convertView.findViewById(R.id.progressBar_imageloading); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } ItemData itemData = dataList.get(position); //启动图片下载任务 try { URL url = new URL(itemData.imageUrl); if(mCacheMap.containsKey(url)) { holder.imageView.setImageBitmap(mCacheMap.get(url)); } else { LoadImageTask imageTask = new LoadImageTask(holder.imageView,holder.progressBar_imageLoading); imageTask.execute(url); } } catch (MalformedURLException e) { e.printStackTrace(); } holder.textView_title.setText(itemData.title); holder.textView_from.setText(itemData.from); holder.textView_time.setText(itemData.time); return convertView; } @Override public long getItemId(int position) { return 0; } @Override public Object getItem(int position) { return null; } @Override public int getCount() { return dataList.size(); } }; } //下载图片 class LoadImageTask extends AsyncTask<URL, Void, Bitmap> { private ImageView imageView; ProgressBar progressBar_imageLoading; public LoadImageTask(ImageView imageView, ProgressBar progressBar_imageLoading) { this.imageView = imageView; this.progressBar_imageLoading = progressBar_imageLoading; } @Override protected void onPreExecute() { progressBar_imageLoading.setVisibility(View.VISIBLE); } //下载图片 @Override protected Bitmap doInURL... params) { InputStream is = null; Bitmap bitmap = null; try { //判断网络连接 HttpURLConnection conn = (HttpURLConnection) params[0].openConnection(); conn.setConnectTimeout(Contant.HTTP_TIME_OUT); conn.setReadTimeout(Contant.HTTP_TIME_OUT); if(conn.getResponseCode() != HttpURLConnection.HTTP_OK) { return null; } //由url获取bitmap对象 is = conn.getInputStream(); //简写方法:is = params[0].openStream() bitmap = BitmapFactory.decodeStream(is); mCacheMap.put(params[0], bitmap); } catch (IOException e) { e.printStackTrace(); } finally { if(null != is ) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { if(bitmap == null) { //图片加载失败 } else { progressBar_imageLoading.setVisibility(View.INVISIBLE); imageView.setImageBitmap(bitmap); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.watching, menu); return true; } }
其他优化和扩展:
1.图片加载 与设置图片方法一样,将控件对象传到异步任务里
2.惰性加载
其他相关:
1.隐藏headview
<LinearLayout android:id="@+id/item_root" android:layout_width="fill_parent" android:layout_height="50dip" android:orientation="vertical" > <LinearLayout android:id="@+id/item_container" <TextView android:id="@+id/tv_1" /> <TextView android:id="@+id/tv_2" /> </LinearLayout> </LinearLayout >要隐藏的view必须不能是根目录的view的id。
相关文章推荐
- Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)
- android结合异步任务,动态加载图片,Json解析数据展示在ListView,并且实现按日期分类展示,借口回调
- Android利用Volley异步加载数据(JSON和图片)完整示例
- Android利用Volley异步加载数据(JSON和图片)完整示例
- Android ListView&异步加载的学习(二)——多线程加载图片
- android listview利用多线程异步加载图片并更新视图
- Android异步下载网络图片&android解析xml文件的方式&使用Adapter为ListView提供数据
- volley学习笔记(四):Android利用Volley异步加载数据(JSON和图片)完整示例
- Android:ListView异步加载图片(实现网络下载、存储本地、缓存内存、压缩显示)
- Android异步加载学习笔记之二:实现ListView中的图片数据从网络加载
- Android利用Volley异步加载数据(JSON和图片)完整示例
- Android异步下载网络图片&android解析xml文件的方式&使用Adapter为ListView提供数据
- Android异步加载学习笔记之三:用AsyncTask实现ListView中的图片数据加载
- Android新浪微博client(七)——ListView图片异步加载、高速缓存
- android ListView 多线程异步加载Url图片
- Android 解决ListView异步加载网络数据(图片文字)出现位置错乱以及优化ListView的加载
- 使用异步任务加载网络上json数据并加载到ListView中
- ★android开发--ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)
- android开发---ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)
- Android利用Volley异步加载数据(JSON和图片)完整示例