Android 项目开发框架 Bertha 。 2022-08-19 01:50 100阅读 0赞 今天这篇文章,主要是为了快速搭建一个项目主体框架! 目前好多应用的主界面都是,底部几个切换按钮,点击不同的按钮,切换不同的界面,先来几张截图,如下, ![Center][] ![Center 1][] ![Center 2][] 这三张截图,分别来自淘宝、京东、网易新闻,都是目前用户使用量比较多的,并且,我在实际的项目中,用这个样式的也比较多。那么今天,我们就简单实现这样一个项目框架。 先看2张我实现的效果图, ![Center 3][] ![Center 4][] 这是我仿照网易新闻客户端做的!看着效果还行!O(∩\_∩)O!那么我们就开始今天的学习。 一.新建项目; ![Center 5][] 二.新建布局文件,activity\_home.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="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/navigation_tab_ll" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@color/color_aaaaaa" android:orientation="horizontal" android:paddingTop="1dp" android:weightSum="5" > <LinearLayout android:id="@+id/id_news_ll" style="@style/style_navigation_tab_ll" > <ImageView android:id="@+id/id_news_iv" style="@style/style_navigation_tab_iv" android:background="@drawable/biz_navigation_tab_news_selected" /> <TextView android:id="@+id/id_news_tv" style="@style/style_navigation_tab_tv" android:text="新闻" android:textColor="@color/color_eb413d" /> </LinearLayout> <LinearLayout android:id="@+id/id_read_ll" style="@style/style_navigation_tab_ll" > <ImageView android:id="@+id/id_read_iv" style="@style/style_navigation_tab_iv" android:background="@drawable/biz_navigation_tab_read" /> <TextView android:id="@+id/id_read_tv" style="@style/style_navigation_tab_tv" android:text="阅读" android:textColor="@color/color_aaaaaa" /> </LinearLayout> <LinearLayout android:id="@+id/id_va_ll" style="@style/style_navigation_tab_ll" > <ImageView android:id="@+id/id_va_iv" style="@style/style_navigation_tab_iv" android:background="@drawable/biz_navigation_tab_va" /> <TextView android:id="@+id/id_va_tv" style="@style/style_navigation_tab_tv" android:text="视听" android:textColor="@color/color_aaaaaa" /> </LinearLayout> <LinearLayout android:id="@+id/id_topic_ll" style="@style/style_navigation_tab_ll" > <ImageView android:id="@+id/id_topic_iv" style="@style/style_navigation_tab_iv" android:background="@drawable/biz_navigation_tab_topic" /> <TextView android:id="@+id/id_topic_tv" style="@style/style_navigation_tab_tv" android:text="话题" android:textColor="@color/color_aaaaaa" /> </LinearLayout> <LinearLayout android:id="@+id/id_pc_ll" style="@style/style_navigation_tab_ll" > <ImageView android:id="@+id/id_pc_iv" style="@style/style_navigation_tab_iv" android:background="@drawable/biz_navigation_tab_pc" /> <TextView android:id="@+id/id_pc_tv" style="@style/style_navigation_tab_tv" android:text="我" android:textColor="@color/color_aaaaaa" /> </LinearLayout> </LinearLayout> <FrameLayout android:id="@+id/home_fl" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/navigation_tab_ll" /> </RelativeLayout> 底部是5个可以选择的控件,这些布局之上是一个FrameLayout,FrameLayout是用来当点击底部不同的控件显示不同的布局。这个很简单! 我们这个里面用到Fragment(当你点击不同的控件时,显示的是不同Fragment),这是Android3.0后给出的,它很方便的解决了在pad或者大屏幕上app适配的问题(也就是说,只要你在代码中控制,那么一套代码就可以在手机、平板等设备上都可以适用,并且显出的效果会根据设备有所调整),官方也大力推荐我们在项目中使用它。现在v4包里面已经有Fragment,当我们向下兼容时,导入v4包就可以了。 接着,我们需要创建5个fragment\_\*.xml布局文件,这5个布局文件都差不多,只是显示的文字不一样,所以,那看其中一个的布局,fragment\_news.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="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="新闻" android:textSize="20sp" android:textColor="@color/color_eb413d" /> </RelativeLayout> 该布局就只显示一个TextView,fragment\_\*.xml其他的布局都差不多。 三.新建Fragment,我们就只看看NewsFragment的实现, /** * 新闻 */ public class NewsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view=inflater.inflate(R.layout.fragment_news, container, false); return view; } /* (non-Javadoc) * 当Fragment隐藏或者显示的时候调用 * @see android.support.v4.app.Fragment#onHiddenChanged(boolean) */ @Override public void onHiddenChanged(boolean hidden) { // TODO Auto-generated method stub super.onHiddenChanged(hidden); if(hidden){// 不在最前端界面显示 }else{// 重新显示到最前端中 } } } onCreateView(),这个方法是当Fragment加载布局时调用的,onHiddenChanged(),该方法当Fragment隐藏或者显示的时候调用(我们在某些时候每次当显示Fragment时都应该显示最新的数据就可以用,详细的可以看这篇文章:[Fragment hide,show方法后,会调用什么方法][Fragment hide_show])。其他的Fragment的实现和这个都类似,唯一不一样的地方就是加载的布局文件不一样。 四.新建Activity,我在项目中,定义了一个Activity基类,BaseActivity,,让它继承FragmentActivity /** * activity基类 */ public class BaseActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(); initView(); setListener(); loadData(); } /** * 加载布局 */ protected void setContentView() { } /** * 绑定控件 */ protected void initView() { } /** * 设置监听事件 */ protected void setListener() { } /** * 加载数据 */ protected void loadData() { } } 定义了一些方法,把代码分类。我们新建HomeAcivity,继承BaseActivity,代码如下, /** * 主布局 */ @SuppressWarnings("deprecation") public class HomeAcivity extends BaseActivity implements OnClickListener { private FragmentManager fragmentManager;// Fragment管理 private NewsFragment newsFragment;//新闻 private ReadFragment readFragment;//阅读 private VaFragment vaFragment;//视听 private TopicFragment topicFragment;//话题 private MemberFragment memberFragment;//我 private ImageView newsIv; private ImageView readIv; private ImageView vaIv; private ImageView topicIv; private ImageView memberIv; private TextView newsTv; private TextView readTv; private TextView vaTv; private TextView topicTv; private TextView memberTv; private String tag = "0";//当前位置的标识 private boolean isAppExit; // app退出标志位 public static final int APPEXIT = -1;// @Override protected void setContentView() { setContentView(R.layout.activity_home); } @Override protected void initView() { newsIv = (ImageView) findViewById(R.id.id_news_iv); readIv = (ImageView) findViewById(R.id.id_read_iv); vaIv = (ImageView) findViewById(R.id.id_va_iv); topicIv = (ImageView) findViewById(R.id.id_topic_iv); memberIv = (ImageView) findViewById(R.id.id_pc_iv); newsTv = (TextView) findViewById(R.id.id_news_tv); readTv = (TextView) findViewById(R.id.id_read_tv); vaTv = (TextView) findViewById(R.id.id_va_tv); topicTv = (TextView) findViewById(R.id.id_topic_tv); memberTv = (TextView) findViewById(R.id.id_pc_tv); } @Override protected void setListener() { findViewById(R.id.id_news_ll).setOnClickListener(this); findViewById(R.id.id_read_ll).setOnClickListener(this); findViewById(R.id.id_va_ll).setOnClickListener(this); findViewById(R.id.id_topic_ll).setOnClickListener(this); findViewById(R.id.id_pc_iv).setOnClickListener(this); newsIv.setOnClickListener(this); readIv.setOnClickListener(this); vaIv.setOnClickListener(this); topicIv.setOnClickListener(this); memberIv.setOnClickListener(this); } @Override protected void loadData() { fragmentManager = getSupportFragmentManager(); setTabSelection(0); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.id_news_ll: case R.id.id_news_iv: setTabSelection(0); break; case R.id.id_read_ll: case R.id.id_read_iv: setTabSelection(1); break; case R.id.id_va_ll: case R.id.id_va_iv: setTabSelection(2); break; case R.id.id_topic_ll: case R.id.id_topic_iv: setTabSelection(3); break; case R.id.id_pc_ll: case R.id.id_pc_iv: setTabSelection(4); break; default: break; } } /** * @param index */ private void setTabSelection(int index) { // 每次选中之前先清除掉上次的选中状态 clearSelection(); // 开启一个Fragment事务 FragmentTransaction transaction = fragmentManager.beginTransaction(); // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况 hideFragments(transaction); switch (index) { case 0: tag = "0"; newsIv.setBackgroundResource(R.drawable.biz_navigation_tab_news_selected); newsTv.setTextColor(getResources().getColor(R.color.color_eb413d)); if (newsFragment == null) { // 如果BrandSaleFragment为空,则创建一个并添加到界面上 newsFragment = new NewsFragment(); // mallFragment.setArguments(bundle); transaction.add(R.id.home_fl, newsFragment); } else { // 如果MessageFragment不为空,则直接将它显示出来 transaction.show(newsFragment); } break; case 1: tag = "1"; readIv.setBackgroundResource(R.drawable.biz_navigation_tab_read_selected); readTv.setTextColor(getResources().getColor(R.color.color_eb413d)); if (readFragment == null) { // 如果BrandSaleFragment为空,则创建一个并添加到界面上 readFragment = new ReadFragment(); // mallFragment.setArguments(bundle); transaction.add(R.id.home_fl, readFragment); } else { // 如果MessageFragment不为空,则直接将它显示出来 transaction.show(readFragment); } break; case 2: tag = "2"; vaIv.setBackgroundResource(R.drawable.biz_navigation_tab_va_selected); vaTv.setTextColor(getResources().getColor(R.color.color_eb413d)); if (vaFragment == null) { // 如果BrandSaleFragment为空,则创建一个并添加到界面上 vaFragment = new VaFragment(); // mallFragment.setArguments(bundle); transaction.add(R.id.home_fl, vaFragment); } else { // 如果MessageFragment不为空,则直接将它显示出来 transaction.show(vaFragment); } break; case 3: tag = "3"; topicIv.setBackgroundResource(R.drawable.biz_navigation_tab_topic_selected); topicTv.setTextColor(getResources().getColor(R.color.color_eb413d)); if (topicFragment == null) { // 如果BrandSaleFragment为空,则创建一个并添加到界面上 topicFragment = new TopicFragment(); // mallFragment.setArguments(bundle); transaction.add(R.id.home_fl, topicFragment); } else { // 如果MessageFragment不为空,则直接将它显示出来 transaction.show(topicFragment); } break; case 4: tag = "4"; memberIv.setBackgroundResource(R.drawable.biz_navigation_tab_pc_selected); memberTv.setTextColor(getResources().getColor(R.color.color_eb413d)); if (memberFragment == null) { // 如果BrandSaleFragment为空,则创建一个并添加到界面上 memberFragment = new MemberFragment(); // mallFragment.setArguments(bundle); transaction.add(R.id.home_fl, memberFragment); } else { // 如果MessageFragment不为空,则直接将它显示出来 transaction.show(memberFragment); } break; } transaction.commit(); } /** * 清除掉所有的选中状态。 */ private void clearSelection() { newsIv.setBackgroundResource(R.drawable.biz_navigation_tab_news); readIv.setBackgroundResource(R.drawable.biz_navigation_tab_read); topicIv.setBackgroundResource(R.drawable.biz_navigation_tab_topic); vaIv.setBackgroundResource(R.drawable.biz_navigation_tab_va); memberIv.setBackgroundResource(R.drawable.biz_navigation_tab_pc); newsTv.setTextColor(getResources().getColor(R.color.color_aaaaaa)); readTv.setTextColor(getResources().getColor(R.color.color_aaaaaa)); topicTv.setTextColor(getResources().getColor(R.color.color_aaaaaa)); vaTv.setTextColor(getResources().getColor(R.color.color_aaaaaa)); memberTv.setTextColor(getResources().getColor(R.color.color_aaaaaa)); } /** * 将所有的Fragment都置为隐藏状态。 * * @param transaction * 用于对Fragment执行操作的事务 */ private void hideFragments(FragmentTransaction transaction) { if (newsFragment != null) { transaction.hide(newsFragment); } if (readFragment != null) { transaction.hide(readFragment); } if (topicFragment != null) { transaction.hide(topicFragment); } if (vaFragment != null) { transaction.hide(vaFragment); } if (memberFragment != null) { transaction.hide(memberFragment); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (tag.equals("1") || tag.equals("2") || tag.equals("3")|| tag.equals("4")) { setTabSelection(0); } else if (tag.equals("0")) { appExit(); } return true; } return super.onKeyDown(keyCode, event); } /** * 退出app */ public void appExit() { if (!isAppExit) { isAppExit = true; Toast.makeText(this, "再按一次,退出应用", Toast.LENGTH_SHORT).show(); handler.sendEmptyMessageDelayed(APPEXIT, 2000); } else { // 2s内再次按back时,isExit= true,执行以下操作,app退出 System.exit(0); } } Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case APPEXIT: isAppExit = false; break; default: break; } }; }; } 首先设置布局,接着绑定控件,设置监听事件,当点击不同的控件时,调用setTabSelection()方法,在该方法中, 1.清除控件之前的状态,clearSelection(); 2.隐藏所有的 Fragment,hideFragments(); 3.根据传递的index参数,进入到相应的case中,先改变当前控件的状态,接着,判断当前Fragment是否为null,当为null时,创建该Fragment,并将该Fragment加入到FragmentManager,管理起来,当不为null时,就直接显示该Fragment,记得还要提交该事务,transaction.commit()。 经过上面这几步,就可以实现基本的功能了!我还实现了,onKeyDown()监听事件(点击手机返回键时的监听),当点击返回键时,如果当前显示的不是主Fragment,那么先跳转到主Fragment,此时,再次点击返回键时,便会看到提示“再按一次,退出应用”,若果是主Fragment,就如前面所说的。 至此,经过上面的流程,我们就能大致实现文章开头时,展示的项目样式,我们在实际开发中,只需要更换图片等一些简单的操作,就可以很快实现这样的项目样式!该项目样式的实现,得益于很早之前看郭霖大牛的博客,所以,在此感谢郭霖大牛! 如果该文章你已经了解,那么可以去看看这些文章,[打造属于你的万能适配器][Link 1]和[Android 滑动切换][Android]! 如果你也需要实现这样的项目框架样式,那么请下载源码吧! **ps:[源码下载地址][Link 2]** [Center]: https://img-blog.csdn.net/20151230175912481?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center [Center 1]: /images/20220731/f427cdee60f6430fbc71dc3504255c2e.png [Center 2]: /images/20220731/a5f54d7aa51f4f33bfc2ede05913965b.png [Center 3]: https://img-blog.csdn.net/20151230182032682?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center [Center 4]: /images/20220731/ae8a3c341aec47989f0ee08099ff4e42.png [Center 5]: /images/20220731/3c25d172786942e18cf60644a8f15100.png [Fragment hide_show]: http://blog.csdn.net/zxw136511485/article/details/46625063 [Link 1]: http://blog.csdn.net/zxw136511485/article/details/50429402 [Android]: http://blog.csdn.net/zxw136511485/article/details/18656129 [Link 2]: http://download.csdn.net/detail/zxw136511485/9384996
还没有评论,来说两句吧...