Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)

解析服务端JSON的内容和图片,通过异步任务下载并设置到listview页上,点击listview跳转到详情页。

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。








本文出自 “天空没有痕迹但我飞过” 博客,转载请与作者联系!

你可能感兴趣的:(json,bitmap,图片加载,数据下载,Listview加载项目)