今天我们来编写一个新闻客户端的案例,里面用到了很多知识点
1.SmartImageView的使用
市面上一些常见软件,例如手机QQ、天猫、京东商场等,都加载了大量网络上的图片。用Android自带的API实现这一功能十分麻烦而且耗时。为此,编程爱好者开发了一个开源项目——SmartImageView。https://github.com/loopj/android-smart-image-view 开源项目SmartImageView的出现主要是为了加速从网络上加载图片,它继承自ImageView类,支持根据URL地址加载图片、支持异步加载图片、支持图片缓存等。
2.AsyncHttpClient的使用
在Android开发中,发送、处理HTTP请求十分常见,如果每次与服务器进行数据交互都需要去开启一个子线程,这样是非常麻烦的。为了解决这个问题,一些开发者开发出了开源项目——AsyncHttpClient。https://github.com/loopj/android-async-http http://hc.apache.org/download.cgi
AsyncHttpClient是对HttpClient的再次包装。AsyncHttpClient的特点有,发送异步HTTP请求、HTTP请求发生在UI线程之外、内部采用了线程池来处理并发请求,而且它使用起来比HttpClient更加简便。
3.配置Tomcat服务器
http://tomcat.apache.org/ 下载并通过startup.bat启动服务器
在webapps/Root文件夹下:JSON文件和images文件夹
一.布局界面
1.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="cn.edu.bzu.news.MainActivity"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/loading" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="invisible" android:gravity="center" android:orientation="vertical"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="正在加载信息..."/> </LinearLayout> <ListView android:id="@+id/iv_news" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </FrameLayout> </LinearLayout>2.news_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="65dp"> <com.loopj.android.image.SmartImageView android:id="@+id/siv_icon" android:layout_width="80dp" android:layout_height="60dp" android:layout_alignParentLeft="true" android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:scaleType="centerCrop" android:src="@drawable/a"/> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="10dp" android:layout_toRightOf="@id/siv_icon" android:text="我是标题" android:maxLength="20" android:lines="1" android:ellipsize="end" android:textColor="#000000" android:textSize="10sp"/> <TextView android:id="@+id/tv_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tv_title" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_toRightOf="@id/siv_icon" android:text="我是描述" android:maxLength="16" android:ellipsize="end" android:lines="1" android:textColor="#99000000" android:textSize="14sp"/> <TextView android:id="@+id/tv_type" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="5dp" android:text="评论" android:textColor="#99000000" android:textSize="12sp"/> </RelativeLayout>
二.MainActivity.java
public class MainActivity extends AppCompatActivity { private ListView lvNews; private List<NewsInfo> newsInfos; private LinearLayout loading; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); lvNews=(ListView)findViewById(R.id.iv_news); loading=(LinearLayout)findViewById(R.id.loading); fillData(); } private void fillData() { AsyncHttpClient client =new AsyncHttpClient(); client.get("http://10.61.20.106:8080/NewsInfo.json",new AsyncHttpResponseHandler() { public void onSuccess(int i, PreferenceActivity.Header[] healers, byte[] bytes) { String json = null; try { json = new String(bytes, "utf-8"); newsInfos = JsonParse.getNewsInfo(json); if (newsInfos == null) { Toast.makeText(MainActivity.this, "解析失败", Toast.LENGTH_LONG).show(); } else { //更新界面 loading.setVisibility(View.INVISIBLE); lvNews.setAdapter(new NewsAdapter(MainActivity.this, newsInfos)); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } public void onFailure(int i, PreferenceActivity.Header[] healers, byte[] bytes, Throwable throwable) { } } } }
三.在adapter包下创建NewsAdapter类
public class NewsAdapte extends ArrayAdapter<NewsInfo> { public NewsAdapte(Context context, List<NewsInfo> objects) { super(context, R.layout.news_item, objects); } public View getView(int position, View convertView, ViewGroup parent) { NewsInfo newsinfo= getItem(position);//传递position,获取当前位置对应的newsinfo新闻信息 View view=null; viewHolder viewHolder; if(convertView==null){ //判断convertView中是否加载了布局,有没有缓存。为空说明没有缓存 view= LayoutInflater.from(getContext()).inflate(R.layout.news_item,null); viewHolder=new viewHolder(); viewHolder.siv= (SmartImageView) view.findViewById(R.id.siv_icon); viewHolder.tv_title= (TextView) view.findViewById(R.id.tv_title); viewHolder.tv_description= (TextView) view.findViewById(R.id.tv_description); viewHolder.tv_type= (TextView) view.findViewById(R.id.tv_type); view.setTag(viewHolder); //保存 }else{ view=convertView; viewHolder=(viewHolder) view.getTag(); } viewHolder.siv.setImageUrl(newsinfo.getIcon()); viewHolder.tv_title.setText(newsinfo.getTitle());//传递题目 viewHolder.tv_description.setText(newsinfo.getDescription()); viewHolder.tv_type.setText(newsinfo.getType()+""); return view; } class viewHolder{//添加类,封装需要查找的控件 TextView tv_title; TextView tv_description; TextView tv_type; SmartImageView siv; } }四.在entity包下创建NewsInfo
public class NewsInfo { private String icon; private String title; private String content; private int type; private long comment; public NewsInfo(String icon, String title, String content, int type, long comment) { this.icon = icon; this.title = title; this.content = content; this.type = type; this.comment = comment; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int getType() { return type; } public void setType(int type) { this.type = type; } public long getComment() { return comment; } public void setComment(long comment) { this.comment = comment; } public int getDescription() { return description; } }五.在tools包下创建JSonParse
public class JsonParse { public static List<NewsInfo>getNewsInfo(String json){ //使用gson库解析JSON数据 Cosn gson = new Cosn(); //创建一个TypeToken的匿名子类对象,并调用对象的getType()方法 Type listType=new TypeToken<List<NewsInfo>>(){ }.getType(); //把获取到的信息集合存到newsInfos中 List<NewsInfo>newsInfos=gson.fromJson(json,listType); return newsInfos; } }
运行图