版本更新、滑动启动页、图片异步加载、抓取html网页新闻、内嵌小说阅读功能、PageView轮播图展示功能
2015-09-24 17:22
716 查看
本项目完全是自己手工编写,基于增加在校学生的实践经验,当然有需要的可以联系获取源代码,可以用于安卓的毕业设计:
好了直接上图,大家先预览下
在线跟新更新版本功能
在这里我使用Handle机制通过解析JSON获取服务器端的版本信息,通过获取的服务端设定的版本信息,如果版本号相同就不进行更新,如果不同则更新,下面是服务端的代码:
>
这里的技术要点就2个,①Json数据解析,json安卓直接封装好了,大家直接使用即可,如果对json解析不清楚的,可以阅读这位前辈的文章http://blog.csdn.net/onlyonecoder/article/details/8490924 ②Handle机制,这里使用handler的原因就是加载网络可能延时,于是直接开启了子线程中进行网络数据的加载,因为子线程不能更新主线程的UI,于是就直接借用了handle来完成主线程的更新,当然大家可以使用安卓自带的异步加载任务类Asynctask,同样可以实现异步加载,更新数据。
下面是handler的实现方法,可以参考看下:
好了直接上图,大家先预览下
好了,基本的展示都已经放上去了,接下来我就给大家细细的讲解下里面用到的技术,其实都不难,大家慢慢看下就会了(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项目,但是感觉有点拿不出手,当然了楼主热爱移动互联网的开发,也会一直投入移动互联网的开发,个人感觉移动互联网到处是生机和活力。
相关文章推荐
- php结合安卓客户端实现查询交互实例
- Android安卓中循环录像并检测内存卡容量
- 在安卓系统中插入表情到光标位置的代码详解
- Almp 安卓系统上搭建本地php服务器环境的步骤
- 谷歌被屏蔽后如何搭建安卓环境
- 安卓APP测试之使用Burp Suite实现HTTPS抓包方法
- 分享一个安卓的内置多种工具类的Activity
- 安卓系统中实现摇一摇画面振动效果的方法
- 安卓(Android)中如何实现滑动导航
- 六款值得推荐的android(安卓)开源框架简介
- 浅谈Android虚拟机的动态加载技术
- 安卓系统手机无法连接***
- android intent和intent action大全
- OGEngine介绍
- OGEngine_修改器
- OGEngine 弹出软件盘手动输入文字处理
- OGEngine 弹出软件盘手动输入文字处理
- 【游戏推荐】癞子斗地主--OGEngine精品游戏推荐系列【一】