Ace教你一步一步做Android新闻客户端(一)
复制粘贴了那么多博文很不好意思没点自己原创的也说不出去,现在写一篇一步一步教你做安卓新闻客户端,借此机会也是让自己把相关的技术再复习一遍,大神莫笑,专门做给新手看。
手里存了两篇,一个包括软件视图 和新手引导 软件侧滑菜单 滑动主页的GUI篇
一个内容解析篇。
代码里有很详细的注释 所以直接放代码了 有不会的站内信或者评论我会及时回复。
MainActivity XML :只有一个ListView布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="asynctask.zb.com.asynctask_02.MainActivity"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listview" /> </RelativeLayout>
adapter_item .XML 图片暂用系统默认 明天发图片异步加载和优化的文再讲
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="horizontal" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:padding="0dp"> 7 <ImageView 8 android:id="@+id/tvimage" 9 android:layout_width="64dp" 10 android:layout_height="64dp" 11 android:src="@mipmap/ic_launcher" /> 12 13 14 <LinearLayout 15 android:layout_width="match_parent" 16 android:layout_height="match_parent" 17 android:orientation="vertical" 18 android:padding="0dp"> 19 20 <TextView 21 android:layout_width="283dp" 22 android:layout_height="wrap_content" 23 android:singleLine="true" 24 android:id="@+id/tvtitle" 25 android:text="这是标题" 26 android:paddingLeft="5dp" 27 android:textSize="20sp"/> 28 29 <TextView 30 android:layout_width="262dp" 31 android:layout_height="wrap_content" 32 android:maxLines="3" 33 android:id="@+id/tvcontent" 34 android:text="这是内容" 35 android:paddingTop="2dp" 36 android:paddingLeft="5dp" 37 android:textSize="12dp" 38 /> 39 </LinearLayout> 40 </LinearLayout>
===========================================
MainActivity:
1 。
获取到jsonString Log.d(TAG, jsonString);打印下是否可以获取到JSON数据
2.在
return nesBeanList;
处设置断点查看下返回的List<NewsBean>
package asynctask.zb.com.asynctask_02; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.ListView; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { //初始化 String TAG = "zbace";//日志TAG private ListView listView; private String URL =" http://www.imooc.com/api/teacher?type=4&num=30"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listview); new NewsAsyncTask().execute(URL); } /** Ace in 2016/1/20 * 创建getJsonData(传入URL地址), 把从流中读取的JSON数据封装进NewsBean中放入List集合 * 1 调用readString方法获取到jason格式的字符串, openStream与url.openConnection().geTinpuStream() 一样; * 获取到jsonString Log.d(TAG, jsonString);打印下是否可以获取到JSON数据 * 2 然后创建JSONObject对象,传入jsonString。 * 3 getJSONArray("data")方法 从中取出JSONArray, * 在创建个for循环遍历JSONArray并取出newsicon,title,content,等信息 * 最后把信息放入NewsBean,再添加进数组 * */ private List<NewsBean> getJsonData(String url){ List<NewsBean> nesBeanList = new ArrayList<>(); try { String jsonString = readStream(new URL(url).openStream()); Log.d(TAG, jsonString); JSONObject jsonObject; NewsBean newsBean; try { jsonObject = new JSONObject(jsonString); JSONArray jsonArray = jsonObject.getJSONArray("data"); for (int i = 0 ; i <jsonArray.length(); i++ ){ //每个JSONArray 的元素都是一个JSONObject jsonObject = jsonArray.getJSONObject(i); //把得到的jsonObject, 放入NewsBean newsBean = new NewsBean(); newsBean.newsIconUrl = jsonObject.getString("picSmall"); newsBean.newsTitle = jsonObject.getString("name"); newsBean.newsContent = jsonObject.getString("description"); nesBeanList.add(newsBean); } } catch (JSONException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } return nesBeanList; //记得返回list } /** Ace in 2016/1/20 * readStream方法是为了读取流中的数据从而获得流里的JSONString * * */ private String readStream(InputStream is){ InputStreamReader isr; String result = ""; try { String line = ""; //用把字节流转换为字符流(不转字符流无法显示中文),并设置编码为UTF-8; isr = new InputStreamReader(is,"utf-8"); //套上缓冲流 BufferedReader br = new BufferedReader(isr); //创建一个while循环 while ((line=br.readLine()) != null ){ result += line;//这就得到了我们需要的JSON字符串,从JSON字符串中就可以得到我们想要数据 } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } /** Ace in 2016/1/20 * 异步获取JSON数据 * * */ class NewsAsyncTask extends AsyncTask<String,Void,List<NewsBean>>{ @Override protected List<NewsBean> doInBackground(String... params) { return getJsonData(params[0]);//params就是我们传进来的String URL 网址 只传进来了一个 就输入[0] } @Override protected void onPostExecute(List<NewsBean>nesBeanList) { super.onPostExecute(nesBeanList); NewsAdapter newsAdapter = new NewsAdapter(MainActivity.this ,nesBeanList); listView.setAdapter(newsAdapter); } } }
================
NewsAdapter ViewHolder
package asynctask.zb.com.asynctask_02; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; /** * Created by Ace on 2016/1/20. */ public class NewsAdapter extends BaseAdapter { private List<NewsBean> mlist; private LayoutInflater mInflater; public NewsAdapter(Context context,List<NewsBean>data){ //映射下 把data传给mlist mlist = data; //从一个Context中,获得一个布局填充器,这样你就可以使用这个填充器的inflater.inflate()来把xml布局文件转为View对象了,然后利用view对象,findViewById就可以找到布局中的组件 mInflater = LayoutInflater.from(context); } @Override public Object getItem(int position) { return mlist.get(position); } @Override public int getCount() { return mlist.size(); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder= null; if (convertView == null){ viewHolder = new ViewHolder(); convertView = mInflater.inflate(R.layout.adapter_item,null); viewHolder.iconimage = (ImageView)convertView.findViewById(R.id.tvimage); viewHolder.title = (TextView)convertView.findViewById(R.id.tvtitle); viewHolder.content = (TextView)convertView.findViewById(R.id.tvcontent); convertView.setTag(viewHolder); }else{ viewHolder = (ViewHolder)convertView.getTag(); viewHolder.iconimage.setImageResource(R.mipmap.ic_launcher); viewHolder.title.setText(mlist.get(position).newsTitle); viewHolder.content.setText(mlist.get(position).newsContent); } return convertView; } class ViewHolder{ public TextView title; public ImageView iconimage; public TextView content; } }
NewsBean 封装类
package asynctask.zb.com.asynctask_02; /** * Created by Administrator on 2016/1/20. */ public class NewsBean { public String newsIconUrl; public String newsTitle; public String newsContent; }
先就这样回来补上效果图