您的位置:首页 > Web前端 > HTML

版本更新、滑动启动页、图片异步加载、抓取html网页新闻、内嵌小说阅读功能、PageView轮播图展示功能

2015-09-24 17:22 716 查看
本项目完全是自己手工编写,基于增加在校学生的实践经验,当然有需要的可以联系获取源代码,可以用于安卓的毕业设计:

好了直接上图,大家先预览下













好了,基本的展示都已经放上去了,接下来我就给大家细细的讲解下里面用到的技术,其实都不难,大家慢慢看下就会了(LZ只是一个在校生,不好勿拍 )

项目一览图 



一共分为5个模块

第一个功能模块 :app启动的滑动导航栏

在线跟新更新版本功能

/**
* 检查是否有新版本,如果有就升级
*/
private void checkUpdate() {

new Thread() {
public void run() {
// URLhttp://192.168.1.254:8080/updateinfo.html

Message mes = Message.obtain();
long startTime = System.currentTimeMillis();
try {

URL url = new URL(getString(R.string.serverurl));
// 联网
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(4000);
int code = conn.getResponseCode();
if (code == 200) {
// 联网成功
InputStream is = conn.getInputStream();
// 把流转成String
String result = StreamTools.readFromStream(is);
Log.i(TAG, "联网成功了" + result);
// json解析
JSONObject obj = new JSONObject(result);
// 得到服务器的版本信息
String version = (String) obj.get("version");

description = (String) obj.get("description");
apkurl = (String) obj.get("apkurl");

// 校验是否有新版本
if (getVersionName().equals(version)) {
// 版本一致,没有新版本,进入主页面

mes.what = ENTER_HOME;
} else {
// 有新版本,弹出一升级对话框
mes.what = SHOW_UPDATE_DIALOG;

}

}

} catch (MalformedURLException e) {
// TODO Auto-generated catch block
mes.what = URL_ERROR;
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
mes.what = NETWORK_ERROR;
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
mes.what = JSON_ERROR;
} finally {

long endTime = System.currentTimeMillis();
// 我们花了多少时间
long dTime = endTime - startTime;
// 2000
if (dTime < 2000) {
try {
Thread.sleep(2000 - dTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

handler.sendMessage(mes);
}

};
}.start();

}


在这里我使用Handle机制通过解析JSON获取服务器端的版本信息,通过获取的服务端设定的版本信息,如果版本号相同就不进行更新,如果不同则更新,下面是服务端的代码:

{"version":"8.0","description":"新版本添加了小说阅读,美女欣赏,更多精彩,尽请更新中....","apkurl":"http://7oxgv4.com1.z0.glb.clouddn.com/xunxijiangli.apk"}
4000
>

这里的技术要点就2个,①Json数据解析,json安卓直接封装好了,大家直接使用即可,如果对json解析不清楚的,可以阅读这位前辈的文章http://blog.csdn.net/onlyonecoder/article/details/8490924 ②Handle机制,这里使用handler的原因就是加载网络可能延时,于是直接开启了子线程中进行网络数据的加载,因为子线程不能更新主线程的UI,于是就直接借用了handle来完成主线程的更新,当然大家可以使用安卓自带的异步加载任务类Asynctask,同样可以实现异步加载,更新数据。

下面是handler的实现方法,可以参考看下:

/**
* handler实现UI更新操作
*/
private Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case SHOW_UPDATE_DIALOG:// 显示升级的对话框
Log.i(TAG, "显示升级的对话框");
showUpdateDialog();
progressBar.setVisibility(View.VISIBLE);
break;
case ENTER_HOME:// 进入主页面
//enterHome();
break;

case URL_ERROR:// URL错误
//enterHome();
Toast.makeText(getApplicationContext(), "URL错误", 0).show();

break;

case NETWORK_ERROR:// 网络异常
//enterHome();
Toast.makeText(SplashActivity.this, "网络异常", 0).show();
break;

case JSON_ERROR:// JSON解析出错
//enterHome();
Toast.makeText(SplashActivity.this, "JSON解析出错", 0).show();
break;

default:
break;
}
}

};


接下来就是app启动页面滑动的实现方法:逻辑是这样的,直接在每个启动页面的activity中app里面继承一个“手势识别器”GestureDetector,然后通过Intent进行前后的跳转。当然这里要注意需要在每个启动页面跳转完成前加上这个finish()函数,以免按返回键一直返回,影响用户体验,也不利于程序的性能。下面是这个基类的实现代码:

public abstract class BaseSetupActivity extends Activity {
//1.定义一个手势识别器
private GestureDetector detector;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//2.实例化这个手势识别器
detector = new GestureDetector(this, new SimpleOnGestureListener(){

/**
* 当我们的手指在上面滑动的时候回调
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {

//屏蔽在X滑动很慢的情形

if(Math.abs(velocityX)<200){
Toast.makeText(getApplicationContext(), "滑动得太慢了", 0).show();
return true;
}

//屏蔽斜滑这种情况
if(Math.abs((e2.getRawY() - e1.getRawY())) > 100){
Toast.makeText(getApplicationContext(), "不能这样滑", 0).show();

return true;
}

if((e2.getRawX() - e1.getRawX())> 200 ){
//显示上一个页面:从左往右滑动
System.out.println("显示上一个页面:从左往右滑动");
showPre();
return true;

}

if((e1.getRawX()-e2.getRawX()) > 200 ){
//显示下一个页面:从右往左滑动
System.out.println("显示下一个页面:从右往左滑动");
showNext();
return true;
}

return super.onFling(e1, e2, velocityX, velocityY);
}

});
}

public abstract void showNext();
public abstract void showPre();
/**
* 下一步的点击事件
* @param view
*/
public void next(View view){
showNext();

}

/**
*   上一步
* @param view
*/
public void pre(View view){
showPre();

}

//3.使用手势识别器
@Override
public boolean onTouchEvent(MotionEvent event) {
detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
}


关于每个启动页面的动画效果,这里就不多说了,直接用Activity本身的overridePendingTransition(R.anim.tran_in, R.anim.tran_out)方法就可以了。

第二个功能模块 :PageView轮播图和在线视频加载功能

PageView轮播图的实现方法:首先需要导入安卓的android.support.v4.jsr包,该版本只能在安卓3.0以上使用,搭建看下布局文件就明白了。

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="150dp"
/>


下面请看PageView的实现方法,原来和ListView差不多,适配每个item的数据,先来看下pageView的xml文件

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="150dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/viewpager"
android:background="#33000000"
android:orientation="vertical"
android:id="@+id/img_linear"
>

<TextView
android:id="@+id/image_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"

android:textColor="@android:color/white"
/>

<LinearLayout
android:id="@+id/point_group"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content" >
</LinearLayout>
</LinearLayout>


下面是关于pageview的实现代码,我是直接把视频、新闻、美女、小说、设置 这5个页面都是继承的Fragment,然后在MainActivity中分别设置每个的button的监听事件,然后在FragmentTransaction中加载各个Fragment类(关于这个的设计我会在文章最后详细指出),进行展示,关于pageview代码的实现,大家请看下面的代码:

public class VideoFragment extends Fragment implements OnClickListener{

public static final String LOG_TAG = "VideoFragment";
private TextView textview=null;
private ViewPager pageView=null;
private LinearLayout point_group=null;
private LinearLayout linear_layout;
private int[] table={R.drawable.aa,R.drawable.bb,R.drawable.cc,R.drawable.dd,R.drawable.ee};
List<ImageView> listViews=new ArrayList<ImageView>();
private final String[] imageDescriptions = {
"巩俐不低俗,我就不能低俗",
"再唱经典老歌引万人大合唱",
"揭秘北京电影如何升级",
"乐视网TV版大派送",
"热血屌丝的反杀"
};
private int lastPosition;
private ImageView imageview1;
private ImageView imageview2;
private ImageView imageview3;
private ImageView imageview4;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.video_fragment, container,false);
textview=(TextView) view.findViewById(R.id.image_desc);
point_group=(LinearLayout) view.findViewById(R.id.point_group);
pageView=(ViewPager)view. findViewById(R.id.viewpager);

imageview1=(ImageView) view.findViewById(R.id.image_view1);
imageview2=(ImageView) view.findViewById(R.id.image_view2);
imageview3=(ImageView) view.findViewById(R.id.image_view3);
imageview4=(ImageView) view.find
1aa13
ViewById(R.id.image_view4);

imageview1.setOnClickListener(this);
imageview2.setOnClickListener(this);
imageview3.setOnClickListener(this);
imageview4.setOnClickListener(this);

for(int i=0;i<table.length;i++)
{
ImageView imageView=new ImageView(getActivity());
imageView.setImageResource(table[i]);
imageView.setId(i);

listViews.add(imageView);

ImageView point=new ImageView(getActivity());
LinearLayout.LayoutParams params=new LayoutParams(5, 5);
params.rightMargin=10;
point.setLayoutParams(params);
point.setBackgroundResource(R.drawable.point_bg);
if(i==0)
{
point.setEnabled(true);
}else{
point.setEnabled(false);
}
point_group.addView(point);
}
textview.setText(imageDescriptions[0]);
pageView.setAdapter(new MyAdapter());
//设置pageView的时间监听器
pageView.setOnPageChangeListener(new OnPageChangeListener() {
/**
* 当页面滑动的时候设置的事件
*/
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
textview.setText(imageDescriptions[position%(table.length)]);
point_group.getChildAt(position%(table.length)).setEnabled(true);
point_group.getChildAt(lastPosition%(table.length)).setEnabled(false);
lastPosition = position;
//配合Adapter的currentItem字段进行设置。

}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub

}
});
return view;
}

private class MyAdapter extends PagerAdapter
{

@Override
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0==arg1;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
container.removeView((View)object);
object=null;

}

@Override
public Object instantiateItem(ViewGroup container, final int position) {
// TODO Auto-generated method stub
//设置对应页面的监听事件
switch (position%(table.length)) {
case 0:
listViews.get(position%(table.length)).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "我是第"+position+"点", 0).show();
}
});
break;
case 1:
listViews.get(position%(table.length)).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "我是第"+position+"点", 0).show();
}
});
break;
case 2:
listViews.get(position%(table.length)).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "我是第"+position+"点", 0).show();
}
});
break;
case 3:
listViews.get(position%(table.length)).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "我是第"+position+"点", 0).show();
}
});
break;
case 4:
listViews.get(position%(table.length)).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "我是第"+position+"点", 0).show();
}
});
break;
default:
break;
}
container.addView(listViews.get(position%(table.length)));//添加孩子节点到ViewGroup中
return listViews.get(position%(table.length));
}

}

@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch (view.getId()) {
case R.id.image_view1:
sendIntent();
break;
case R.id.image_view2:
sendIntent();
break;
case R.id.image_view3:
sendIntent();
break;
case R.id.image_view4:
sendIntent();
break;

default:
break;
}
}

private void sendIntent()
{
Intent intent=new Intent();
String URL=getString(R.string.videourl);
intent.putExtra("extra", URL);
intent.setClass(getActivity(), VedioActivity.class);
startActivity(intent);
}
}


当然大家会发现点击每个视频都是直接播放同一个视频,那是LZ视频资源不多,所以只放了一个视频链接,这里的视频跳转我需要说下,播放视频是用了一个专门的VedioActivity.class进行播放,不管点击哪视频图片,监听事件里面利用Intent跳转,当然是在里面的Intent来传递网络视频Url地址,具体看代码:

private void sendIntent()
{
Intent intent=new Intent();
String URL=getString(R.string.videourl);
intent.putExtra("extra", URL);
intent.setClass(getActivity(), VedioActivity.class);
startActivity(intent);
}


VedioActivity.class里面接收代码的如下:

Intent intent=getIntent();
String url=intent.getStringExtra("extra");
Uri uri = Uri.parse(url);
videoView.setMediaController(new MediaController(this));
videoView.setVideoURI(uri);
videoView.start();
progress.setVisibility(View.GONE);
videoView.requestFocus();


好了,关于轮播图和视频播放就写到这里,视频的播放这个不难,直接用VideoView控件就可以实现,当然你可以选择用MedioPaly这个类进行实现。

第三个功能模块 :利用Jsoup.jar包对服务器端的html文档抓取新闻,然后ListView控件展示每条新闻,主要技术难点是异步加载新闻图片和抓取html数据,进行封装

下面直接看抓取html网络数据的实现代码吧,导入Jsoup.jar包,网络获取的信息,全部封装到这个newInfos=new ArrayList(),所以这里的newInfos需要设置为全局变量,因为后面的ListView中需要抽取里面的数据,关于解析html的方法,大家可以看这个官方的api http://www.open-open.com/jsoup/

/**
* 获取List<NewInfo>的信息,将网页信息封装在newInfos里面
*   * @return
*/
public void getNewInfoFromInternet(){
try {

//         File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(getHtmlString(htmlUrl));
Elements rowpic = doc.getElementsByClass("row-pic");//通过获取全部href
//Elements images = doc.getElementsByClass("article-newslist-detail-pic-img");
Elements rowdescs = doc.getElementsByClass("row-desc");
newInfos=new ArrayList<NewInfo>();
int i=0;
for(Element e:rowpic)
{
newInfo=new NewInfo();
String href0=e.getElementsByTag("a").attr("href");
String href=baseUrl+href0;
String title=e.getElementsByTag("a").attr("title");
String image=e.getElementsByTag("img").attr("src");
//             String detailSummary=e.getElementsByClass("row-desc").text();
String detailSummary= rowdescs.get(i).getElementsByTag("a").text();
newInfo.setHrefUrl(href);
newInfo.setTitle(title);
newInfo.setImgUrl(image);
newInfo.setDetailSummary(detailSummary);
i++;
newInfos.add(newInfo);
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


下面讲解下ListViewz中加载的条目,关于listview这里不做过多的描述了,因为这个实在是使用太平凡了,无非就是要注意2点:①复用这个convertView,这个很关键,对你的程序的性能优化有很大的帮助,他是直接复用了之前使用过的item,你想啊!当你的Item几万个,你的程序肯定就会崩溃吧,如果复用了convertView,就相当于只需要初始化你屏幕能显示的item。②使用将子view添加到holder中,在创建新的listView的时候,创建新的ViewHolder,把所有孩子全部找到,并把孩子的引用给存起来,通过view.setTag(holder)将引用设置到view中,然后再通过holder,将孩子view设置到此holder中,从而减少以后查询的次数。直接贴上我的代码吧

/**
* 新闻列表LIstview的显示
* @author Administrator
*
*/
public class NewAddapet extends BaseAdapter{

@Override
public int getCount() {
// TODO Auto-generated method stub
return newInfosAddapet.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view=null;
if(convertView==null)
{
LayoutInflater inflate=getLayoutInflater(getArguments());
view=inflate.inflate(R.layout.listview_item, null);

}else{
view=convertView;
}
SmartImageView imageView=(SmartImageView) view.findViewById(R.id.siv_listview_item_icon);
TextView title=(TextView) view.findViewById(R.id.tv_listview_item_title);
TextView detail=(TextView) view.findViewById(R.id.tv_listview_item_detail);
final NewInfo newInfo=newInfosAddapet.get(position);

imageView.setImageUrl(newInfo.getImgUrl());
title.setText(newInfo.getTitle());
detail.setText(newInfo.getDetailSummary());

view.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
String URL=newInfo.getHrefUrl();
intent.putExtra("extra", URL);
intent.setClass(getActivity(), NewActivity.class);
startActivity(intent);
}
});
return view;
}

}


当然这里使用了 开源github的com.loopj.android.image项目,关于他的作用,我这里简要介绍下:

①根据URL地址装载图像;

②支持装载通讯录中的图像;

③支持异步装载;

④支持缓存;

所以这里当然直接就用了,既然前辈们已经写好了图片的加载,我就不客气的直接运行了,发现真的狠方便,你只需要在xml中添加这个控件:

<com.loopj.android.image.SmartImageView
android:id="@+id/siv_listview_item_icon"
android:layout_width="100dip"
android:layout_height="60dip"
android:src="@drawable/a" />


然后直接在代码中把url参数直接放到 imageView.setImageUrl(newInfo.getImgUrl());就可以了,还是狠方便的。

第个四功能模块 :美女图片的加载

涉及的技术就是网页图片的获取,解析html,封装数据,图片的异步加载,缓冲,如何等比例缩小图片等。关于这个就不对说了,还是用之前前辈开发好的com.loopj.android.image项目,处理图片,然后封装数据到listview中显示,大家直接看代码吧,实现起来不难。

public class MeinvFragment extends Fragment {
private static int FLAG = 0;
protected static final int SUCCESS = 1;
protected static final int FALSE = 0;
private List<MeinvInfo> meinvInfos=null;
private List<MeinvInfo> meinvInfosAddapet=null;
private MeinvInfo meinvInfo;
private String htmlUrl = "http://7oxgv4.com1.z0.glb.clouddn.com/meinv1.html";

//美女列表ListView
private ListView listview=null;
//加载的进度条
private ProgressBar jiazai=null;
//消息处理机制
private Handler handler=new Handler(){
/**
* 消息处理
*/
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
//在ListView中进行数据的绑定
case SUCCESS:
meinvInfosAddapet=(List<MeinvInfo>) msg.obj;
jiazai.setVisibility(View.GONE);
listview.setAdapter(new MeiAddapet());
FLAG = 1;
break;
case FALSE:Toast.makeText(getActivity(),"网络出错了",0).show();
default:
break;
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.meinv_fragment, container, false);
jiazai=(ProgressBar) view.findViewById(R.id.jiazai);
//显示ListView视图
listview=(ListView) view.findViewById(R.id.lv_list);
init();
//      while (FLAG != 1) {
////          System.out.println("main thread is waiting");
//        }
//开始加载卖家网的新闻

return view;
}

/**
* 初始化加载卖家网新闻
*/
private void init() {
// TODO Auto-generated method stub
//获取网页数据

new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stu
//通过访问url地址获取数据,解析封装到List<NewInfo>中
getNewInfoFromInternet();
Message msg=new Message();
if(meinvInfos!=null)
{
msg.what=SUCCESS;
msg.obj=meinvInfos;

}else{
msg.what=FALSE;

}
//              runOnUiThread(new Runnable() {
//
//                  @Override
//                  public void run() {
//                      // TODO Auto-generated method stub
//                      newInfosAddapet=newInfos;
//                      MyAddapet myAddapet=new MyAddapet();
//                      lv_list.setAdapter(myAddapet);
//                  }
//              });
handler.sendMessage(msg);
}
}).start();

}
/**
* 通过指定的链接获取html的String数据
* @param urlString
* @return
*/
public String getHtmlString(String urlString) {
try {
URL url = null;
url = new URL(urlString);

URLConnection ucon = null;
ucon = url.openConnection();

InputStream instr = null;
instr = ucon.getInputStream();

BufferedInputStream bis = new BufferedInputStream(instr);

ByteArrayBuffer baf = new ByteArrayBuffer(500);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
return EncodingUtils.getString(baf.toByteArray(), "utf-8");
} catch (Exception e) {
return "";
}
}

/**
* 自定义新闻的视频器
* @author Administrator
*
*/
public class MeiAddapet extends BaseAdapter{

@Override
public int getCount() {
// TODO Auto-generated method stub
return meinvInfosAddapet.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view=null;
if(convertView==null)
{
LayoutInflater inflate=getLayoutInflater(getArguments());
view=inflate.inflate(R.layout.meinv_listview_item, null);

}else{
view=convertView;
}
SmartImageView imageView=(SmartImageView) view.findViewById(R.id.siv_listview_item_icon);
final MeinvInfo meinvInfo=meinvInfosAddapet.get(position);

imageView.setImageUrl(meinvInfo.getImgurl());

return view;
}

}
/**
* 获取List<NewInfo>的信息,将网页信息封装在newInfos里面
*   * @return
*/
public void getNewInfoFromInternet(){
try {

//         File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(getHtmlString(htmlUrl));
Elements imgurls = doc.getElementsByClass("meinv");//通过获取全部href
meinvInfos=new ArrayList<MeinvInfo>();
for(Element e:imgurls)
{
meinvInfo=new MeinvInfo();
String img=e.getElementsByTag("img ").attr("src");

meinvInfo.setImgurl(img);
meinvInfos.add(meinvInfo);
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


第个五功能模块 :小说阅读的实现

直接引用的别人的小说项目,然后自己改改启动,和跳转,OK,就实现了,需要注意的是,第一次加载小说显然狠费时间,于是自己就加入了如下的代码块

/**
* 启动封面后过会转向主界面
*/
public void gotoHome(){
new Thread(new Runnable(){
@Override
public void run() {
initBook();
Intent intent = new Intent();
intent.setClass(getActivity(), HomeActivity.class);
startActivity(intent);
}
}).start();
}

/**
* 将Book类初始化。
* 因为启动界面,一般会显示几秒钟再跳转到主界面。
* 而Book类需要从文件中提取关于书的信息,这可能需要一定时间。所以将书的初始化工作放在启动界面这里。
* 可以节省用户等待的时间。
*/
public void initBook(){
IOHelper.getBook(getActivity());
}


好了,到了这里全部的模块都实现了,还是来说说整体的布局吧,我是在MainActivity.class中直接利用FragmentTransaction这个类来控制每个Fragment类的显示控制,具体大家可以看下代码:

package guojian.androidape.com.Activity;

import guojian.androidape.com.R;
import guojian.androidape.com.Fragment.MeinvFragment;
import guojian.androidape.com.Fragment.MysettingFragment;
import guojian.androidape.com.Fragment.NewsFragment;
import guojian.androidape.com.Fragment.NovelFragment;
import guojian.androidape.com.Fragment.VideoFragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends FragmentActivity implements OnClickListener{

//定义5个Fragment的对象
private VideoFragment vedio;
private NewsFragment  news;
private NovelFragment novel;
private MeinvFragment meinv;
private MysettingFragment mysetting;
//帧布局对象,就是用来存放Fragment的容器
private FrameLayout flayout;
//定义底部导航栏的五个布局
private RelativeLayout vedio_layout;
private RelativeLayout news_layout;
private RelativeLayout meinv_layout;
private RelativeLayout novel_layout;
private RelativeLayout mysetting_layout;
//定义底部导航栏中的ImageView
private ImageView vedio_image;
private ImageView news_image;
private ImageView meinv_image;
private ImageView novel_image;
private ImageView mysetting_image;
//定义底部导航栏中的TextView
private TextView vedio_text;
private TextView news_text;
private TextView meinv_text;
private TextView novel_text;
private TextView mysetting_text;
//定义要用的颜色值
private int whirt = 0xFFFFFFFF;
private int gray = 0xFF7597B3;
private int blue =0xFF0AB2FB;
//定义FragmentManager对象
FragmentManager fManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fManager = getSupportFragmentManager();
initViews();
//默认打开vedio视频界面
setChioceItem(0);
}

//完成组件的初始化
public void initViews()
{
//初始化ImageView
vedio_image = (ImageView) findViewById(R.id.vedio_image);
news_image = (ImageView) findViewById(R.id.news_image);
meinv_image = (ImageView) findViewById(R.id.meinv_image);
novel_image = (ImageView) findViewById(R.id.novel_image);
mysetting_image = (ImageView) findViewById(R.id.mysetting_image);
//初始化TextView
vedio_text = (TextView) findViewById(R.id.vedio_text);
news_text = (TextView) findViewById(R.id.news_text);
meinv_text = (TextView) findViewById(R.id.meinv_text);
mysetting_text = (TextView) findViewById(R.id.mysetting_text);
novel_text = (TextView) findViewById(R.id.novel_text);
//初始化相对布局
vedio_layout = (RelativeLayout) findViewById(R.id.vedio_layout);
news_layout = (RelativeLayout) findViewById(R.id.news_layout);
meinv_layout = (RelativeLayout) findViewById(R.id.meinv_layout);
novel_layout = (RelativeLayout) findViewById(R.id.novel_layout);
mysetting_layout = (RelativeLayout) findViewById(R.id.mysetting_layout);
//设置5个相对布局的监听事件
vedio_layout.setOnClickListener(this);
news_layout.setOnClickListener(this);
meinv_layout.setOnClickListener(this);
novel_layout.setOnClickListener(this);
mysetting_layout.setOnClickListener(this);
}

//重写onClick事件
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.vedio_layout:
setChioceItem(0);
break;
case R.id.news_layout:
setChioceItem(1);
break;
case R.id.meinv_layout:
setChioceItem(2);
break;
case R.id.novel_layout:
setChioceItem(3);
break;
case R.id.mysetting_layout:
setChioceItem(4);
break;
default:
break;
}

}

//定义一个选中一个item后的处理
public void setChioceItem(int index)
{
//重置选项+隐藏所有Fragment
FragmentTransaction transaction = fManager.beginTransaction();
clearChioce();
hideFragments(transaction);
switch (index) {
case 0:
vedio_image.setImageResource(R.drawable.btn_vedio);
vedio_text.setTextColor(blue);
vedio_layout.setBackgroundResource(R.drawable.ic_tabbar_bg_click);
if (vedio == null) {
// 如果fg1为空,则创建一个并添加到界面上
vedio = new VideoFragment();
transaction.add(R.id.content, vedio);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(vedio);
}
break;

case 1:
news_image.setImageResource(R.drawable.btn_news);
news_text.setTextColor(blue);
news_layout.setBackgroundResource(R.drawable.ic_tabbar_bg_click);
if (news == null) {
// 如果fg1为空,则创建一个并添加到界面上
news = new NewsFragment();
transaction.add(R.id.content, news);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(news);
}
break;
case 2:
meinv_image.setImageResource(R.drawable.btn_meinv);
meinv_text.setTextColor(blue);
meinv_layout.setBackgroundResource(R.drawable.ic_tabbar_bg_click);
if (meinv == null) {
// 如果fg1为空,则创建一个并添加到界面上
meinv = new MeinvFragment();
transaction.add(R.id.content, meinv);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(meinv);
}
break;
case 3:
novel_image.setImageResource(R.drawable.btn_novel);
novel_text.setTextColor(blue);
novel_layout.setBackgroundResource(R.drawable.ic_tabbar_bg_click);
if (novel == null) {
// 如果fg1为空,则创建一个并添加到界面上
novel = new NovelFragment();
transaction.add(R.id.content, novel);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(novel);
}
break;
case 4:
mysetting_image.setImageResource(R.drawable.btn_mysettings);
mysetting_text.setTextColor(blue);
mysetting_layout.setBackgroundResource(R.drawable.ic_tabbar_bg_click);
if (mysetting == null) {
// 如果fg1为空,则创建一个并添加到界面上
mysetting = new MysettingFragment();
transaction.add(R.id.content, mysetting);
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(mysetting);
}
break;
}
transaction.commit();
}

//隐藏所有的Fragment,避免fragment混乱
private void hideFragments(FragmentTransaction transaction) {
if (mysetting != null) {
transaction.hide(mysetting);
}
if (novel != null) {
transaction.hide(novel);
}
if (meinv != null) {
transaction.hide(meinv);
}
if (news != null) {
transaction.hide(news);
}
if (vedio!= null) {
transaction.hide(vedio);
}
}

//定义一个重置所有选项的方法
public void clearChioce()
{
vedio_image.setImageResource(R.drawable.btn_vedio);
vedio_layout.setBackgroundColor(whirt);
vedio_text.setTextColor(gray);

news_image.setImageResource(R.drawable.btn_news);
news_layout.setBackgroundColor(whirt);
news_text.setTextColor(gray);

meinv_image.setImageResource(R.drawable.btn_meinv);
meinv_layout.setBackgroundColor(whirt);
meinv_text.setTextColor(gray);

novel_image.setImageResource(R.drawable.btn_novel);
novel_layout.setBackgroundColor(whirt);
novel_text.setTextColor(gray);

mysetting_image.setImageResource(R.drawable.btn_mysettings);
mysetting_layout.setBackgroundColor(whirt);
mysetting_text.setTextColor(gray);
}

}


MainActivity.class的布局文件是

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#FFFFFF" >

<RelativeLayout
android:id="@+id/vedio_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/vedio_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/btn_vedio" />

<TextView
android:id="@+id/vedio_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="视频"
android:textColor="#7597B3" />
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/news_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/news_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/btn_news" />

<TextView
android:id="@+id/news_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="新闻"
android:textColor="#7597B3" />
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/meinv_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/meinv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/btn_meinv" />

<TextView
android:id="@+id/meinv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="美女"
android:textColor="#7597B3" />
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/novel_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/novel_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/btn_novel" />

<TextView
android:id="@+id/novel_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="小说"
android:textColor="#7597B3" />
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/mysetting_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/mysetting_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/btn_novel" />

<TextView
android:id="@+id/mysetting_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="我的"
android:textColor="#7597B3" />
</LinearLayout>
</RelativeLayout>

</LinearLayout>
</LinearLayout>


下面是xml的预览图,大家可以看下:



需要预览的app的可以直接下载,下载地址:

http://7oxgv4.com1.z0.glb.clouddn.com/xunxijiangli.apk

好了,第一次写博客,有表达不清晰的请谅解,接下来楼主就要好好的面试了,大四了,已经快毕业了,大学期间也参加过几个java项目,但是感觉有点拿不出手,当然了楼主热爱移动互联网的开发,也会一直投入移动互联网的开发,个人感觉移动互联网到处是生机和活力。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息