Material Design学习跟随demo解读(一)
2016-11-12 18:28
337 查看
写在前面:有的时候下载一个demo可能不能马上运行成功,会遇到各种编译问题,除了最基本的改改编译版本,其实还有更直接的,直接把main下面的文件,包括java文件,res,mainifest全部复制到一个新建的项目中,然后rebuild。。。这个demo我就是这么做的
添加了
这里application标签下有几个不常用的属性android:allowBackup=”true”:从安卓2.2开始google针对安卓系统和应用开启了一个备份的功能
android:hardwareAccelerated=”false”:控制硬加速,3.0新增
supportsRtl:声明你的application是否愿意支持从右到左(RTL就是right-to-left 的缩写…)的布局
布局很简单,做外层是一个
值得注意的是这里面的一些属性DrawerLayout 设置了
NavigationView需要设置android:layout_gravity=”start”属性,可以填satrt也可以是left或者right,决定了侧滑的位置。和
看include标签下的内容布局
解读:
结构主要分为两部分
第一部分是最外层的
AppBarLayout继承自LinearLayout,但是具有滑动的特点
AppBarLayout is a vertical {@link LinearLayout} which implements many of the features of
* material designs app bar concept, namely scrolling gestures.
ViewPager不用多说
FloatingActionButton:悬浮按钮,继承自ImageButton
Floating action buttons are used for a special type of promoted action. They are distinguished
* by a circled icon floating above the UI and have special motion behaviors related to morphing,
* launching, and the transferring anchor point.
从api解释可知AppBarLayout是垂直的,不能设置方向,AppBarLayout里面垂直放置了
Toolbar:A standard toolbar for use within application content.
TabLayout:TabLayout provides a horizontal layout to display tabs,继承自
注意几个属性:
布局中在
headerLayout里面的布局
没什么特别,就是一个普通的垂直线性布局,略过
普通的menu菜单,
## MainActivity ##
MainActivity部分所有代码都加上了注释,比较值得一提的是转场动画部分,步骤:
获取一个转场动画对象
通过这个对象设置转场执行时间
通过getWindow()设置退出时,显示反方向转场动画,传入转场动画对象。
通过Activity选项调用makeScreneTransionAnimation,返回Activity选项对象,
把Activity选项对象转换为Bundle对象
传入intent中
MainActivity中循环实例化了多个
这个fragment中是通过MyApp.loadOutlineData(mContext);方法加载的本地数据,代码如下:
回到MainActivity中还有一个
加了注释,几乎没什么特别,唯一注意继承的是
除了上面的还有详情页和H5页等,由于篇幅限制,下篇继续。。。。
先看build.gradle文件
直接看依赖包dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' compile 'com.android.support:cardview-v7:24.2.1' compile 'com.android.support:recyclerview-v7:24.2.1' compile 'com.android.support:design:24.2.1' }
添加了
cardview,recyclerviewdesign`三个包,
找到清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.steven.materialdesigncomplex"> <uses-permission android:name="android.permission.INTERNET" /> <application android:name=".MyApp" android:allowBackup="true" android:hardwareAccelerated="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/MyAppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".DetailActivity" android:label="@string/title_activity_detail" android:theme="@style/MyAppTheme"></activity> <activity android:name=".H5Activity" android:screenOrientation="portrait" /> </application> </manifest>
这里application标签下有几个不常用的属性android:allowBackup=”true”:从安卓2.2开始google针对安卓系统和应用开启了一个备份的功能
android:hardwareAccelerated=”false”:控制硬加速,3.0新增
supportsRtl:声明你的application是否愿意支持从右到左(RTL就是right-to-left 的缩写…)的布局
从清单文件中找到入口activity
从清单文件上可以知道MainActivity就是这个demo的入口从xml开始
布局文件activity_main
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawerLayout_main" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/include_content_main" android:layout_width="match_parent" android:layout_height="match_parent"/> <android.support.design.widget.NavigationView android:id="@+id/navigationView_main" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/navigation_header" app:menu="@menu/menu_navigationview"/> </android.support.v4.widget.DrawerLayout>
布局很简单,做外层是一个
DrawerLayout里面只允许有两个子视图,一个作为主界面布局,一个作为侧滑布局,include标签引入的为主布局,
NavigationView导航视图,即侧滑内容,这个
NavigationView就是依赖包design里面的控件,
值得注意的是这里面的一些属性DrawerLayout 设置了
android:fitsSystemWindows="true"和
tools:openDrawer="start"第一个属性设置自适应系统窗口,第二个属性设置打开菜单位置,需要添加命名空间
xmlns:tools="http://schemas.android.com/tools"
NavigationView需要设置android:layout_gravity=”start”属性,可以填satrt也可以是left或者right,决定了侧滑的位置。和
tools:openDrawer="start"搭配使用
,同时也设置了android:fitsSystemWindows=”true”
属性app:headerLayout=”@layout/navigation_header”
设置侧滑界面头部视图app:menu=”@menu/menu_navigationview”
设置侧滑界面菜单视图 也要添加命名空间也可以不是menu,可以是任意自定义布局xmlns:app=”http://schemas.android.com/apk/res-auto”`
看include标签下的内容布局include_content_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/coordinatorLayout_main" android:layout_width="match_parent" android:layout_height="match_parent"> <!--//继承自LinearLayout实际是一个LinearLayout--> <android.support.design.widget.AppBarLayout android:id="@+id/appBarLayout_main" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <!--app:layout_scrollFlags="scroll|enterAlways":滚动标识, 放在哪个视图属性下就代表哪个视图在滚动是将被折叠,与app:layout_behavior一起使用, 就是当设置了app:layout_behavior的视图滚动时, 设置了app:layout_scrollFlags属性的视图会被折叠 --> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_main" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> <!--导航布局继承自HorizontalScrollView--> <android.support.design.widget.TabLayout android:id="@+id/tabLayout_main" android:layout_width="match_parent" android:layout_height="wrap_content"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewPager_main" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="@dimen/fab_margin" android:onClick="clickButton" android:src="@android:drawable/ic_menu_myplaces"/> </android.support.design.widget.CoordinatorLayout>
解读:
结构主要分为两部分
第一部分是最外层的
CoordinatorLayout顾名思义Coordinator是协调这的意思,那么CoordinatorLayout就是协调布局,那么怎么协调呢?往下解读,求索答案。第二部分就是在协调布局内部的
AppBarLayoutViewPager
以及FloatingActionButton`
AppBarLayout继承自LinearLayout,但是具有滑动的特点
AppBarLayout is a vertical {@link LinearLayout} which implements many of the features of
* material designs app bar concept, namely scrolling gestures.
ViewPager不用多说
FloatingActionButton:悬浮按钮,继承自ImageButton
Floating action buttons are used for a special type of promoted action. They are distinguished
* by a circled icon floating above the UI and have special motion behaviors related to morphing,
* launching, and the transferring anchor point.
从api解释可知AppBarLayout是垂直的,不能设置方向,AppBarLayout里面垂直放置了
Toolbar和
TabLayout
Toolbar:A standard toolbar for use within application content.
TabLayout:TabLayout provides a horizontal layout to display tabs,继承自
HorizontalScrollView
注意几个属性:
app:layout_scrollFlags="scroll|enterAlways:滚动标识, 放在哪个视图属性下就代表哪个视图在滚动是将被折叠,与app:layout_behavior一起使用, 就是当设置了app:layout_behavior的视图滚动时, 设置了app:layout_scrollFlags属性的视图会被折叠
布局中在
Toolbar和
ViewPager上分别设置了这两个属性,表示这两个控件是相协调的,而协调者就是最外层的父布局
CoordinatorLayout,所以
CoordinatorLayout是通过
app:layout_scrollFlags和
app:layout_behavior来协调的,设置了
app:layout_scrollFlags属性的是被折叠的视图对象,设置了
app:layout_behavior的视图对象是决定设置了
app:layout_scrollFlags视图对象什么时候折叠,折叠的效果取决于
app:layout_scrollFlags设置的值,值的解释参考这篇文章http://www.jianshu.com/p/7caa5f4f49bd
FloatingActionButton中没有什么特殊的属性,略过。
值得注意的是
CoordinatorLayout必须要和AppBarLayout一起使用,就好比scrollview必须要和LinearLayout一起使用一样headerLayout里面的布局navigation_header
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="120dp" android:background="@drawable/side_nav_bar" android:gravity="center" android:orientation="vertical" android:padding="16dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="@mipmap/yuzhi_logo"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:gravity="center" android:text="Android" android:textColor="#fff" android:textSize="20sp"/> </LinearLayout>
没什么特别,就是一个普通的垂直线性布局,略过
menu
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/action_android" android:icon="@mipmap/ic_dashboard" android:title="Andrioid培训"/> <item android:id="@+id/action_h5" android:icon="@mipmap/ic_event" android:title="HTML5"/> <item android:id="@+id/action_ios" android:icon="@mipmap/ic_headset" android:title="iOS"/> <item android:id="@+id/action_ui" android:icon="@mipmap/ic_forum" android:title="移动UI设计"/> </group> <item android:title="Communicate"> <menu> <item android:id="@+id/nav_share" android:icon="@mipmap/ic_headset" android:title="Share"/> <item android:id="@+id/nav_send" android:icon="@mipmap/ic_forum" android:title="Send"/> </menu> </item> </menu>
普通的menu菜单,
## MainActivity ##
package com.steven.materialdesigncomplex; import android.app.Activity; import android.app.ActivityOptions; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.design.widget.NavigationView; import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.design.widget.TextInputLayout; import android.support.v4.app.Fragment; import android.support.v4.view.GravityCompat; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; import android.transition.ChangeImageTransform; import android.transition.ChangeTransform; import android.transition.Transition; import android.util.Pair; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; import android.widget.Toast; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MainActivity extends AppCompatActivity { //当前上下文 private Context mContext = this; //DrawerLayout对象 private DrawerLayout drawerLayout_main; //NavigationView对象 private NavigationView navigationView_main; //ViewPager对象 private ViewPager viewPager_main; //TabLayout对象 private TabLayout tabLayout_main; //Toolbar对象 private Toolbar toolbar_main; //fragment集合 private List<Fragment> fragmentsList = new ArrayList<Fragment>(); //图片集合 private List<Drawable> imageList = new ArrayList<Drawable>(); //定义用户名和密码输入正确性与否的标记 private boolean flag_username = true; private boolean flag_pwd = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化ToolBar initToolbar(); //初始化视图 initView(); //初始化导航和viewpager initTabsAndViewPager(); } private void initView() { drawerLayout_main = (DrawerLayout) findViewById(R.id.drawerLayout_main); //设置Toolbar上的logo与抽屉同步,实现动画切换效果 ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawerLayout_main, toolbar_main, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawerLayout_main.setDrawerListener(toggle); //同步 toggle.syncState(); //初始化导航试图 navigationView_main = (NavigationView) findViewById(R.id.navigationView_main); //给导航item设置监听 navigationView_main.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { //点击哪个就选中哪个 item.setChecked(true); int tabIndex = 0; switch (item.getItemId()) { case R.id.action_android: tabIndex = 0; break; case R.id.action_h5: tabIndex = 1; break; case R.id.action_ios: tabIndex = 2; break; case R.id.action_ui: tabIndex = 3; break; } //滑动ViewPager,实现TAB切换 viewPager_main.setCurrentItem(tabIndex); //关闭抽屉 drawerLayout_main.closeDrawers(); return true; } }); } private void initToolbar() { toolbar_main = (Toolbar) findViewById(R.id.toolbar_main); // setSupportActionBar(toolbar_main); //重新设置logo前方的图标 //toolbar_main.setNavigationIcon(R.mipmap.ic_menu); //toolbar_main.setLogo(R.mipmap.ic_launcher); //title默认为APP的Label名称,也可以重新设置:例如:setTitle("材料设计综合案例一"); //如果不设置子标题,那么title在垂直居中的位置显示。如果设置则上下各一行显示。可以分别设置文字颜色。 toolbar_main.setSubtitle("介绍"); toolbar_main.setTitleTextColor(Color.WHITE); toolbar_main.setSubtitleTextColor(Color.YELLOW); } /** * 创建菜单 * * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { //加载菜单视图 getMenuInflater().inflate(R.menu.menu_main, menu); return true; } private void initTabsAndViewPager() { tabLayout_main = (TabLayout) findViewById(R.id.tabLayout_main); //获取所有显示的tab String[] arrTabTitles = getResources().getStringArray(R.array.arrTabTitles); //实例化viewpager viewPager_main = (ViewPager) findViewById(R.id.viewPager_main); //根据tab的数量,循环创建fragement,并添加到fragment集合中 for (int i = 0; i < arrTabTitles.length; i++) { DummyFragment fragment = DummyFragment.getInstance(i + 1); fragmentsList.add(fragment); } //把集合添加到fragmentStateAdapter PagerAdapter adapter = new MyPagerAdapter( getSupportFragmentManager(), fragmentsList, arrTabTitles); viewPager_main.setAdapter(adapter); //设置tab与viewpager同步 tabLayout_main.setupWithViewPager(viewPager_main); //需要和viewpager一起使用,当adapter改变时,TabLayout会自动的更新 tabLayout_main.setTabsFromPagerAdapter(adapter); } /** * floatActionButton点击事件 * * @param view */ public void clickButton(View view) { // 启动动画 MyApp.startAnimation(view, 500, 1); switch (view.getId()) { case R.id.fab_main: /*Snackbar,比toast更强大,可在内部定义操作*/ Snackbar.make(view, "注册用户可看更多内容!", Snackbar.LENGTH_LONG) .setAction("注册", new View.OnClickListener() { @Override public void onClick(View v) { View registerView = getLayoutInflater().inflate(R.layout.dialog_login, null); final TextInputLayout textInputLayout_username = (TextInputLayout) registerView.findViewById(R.id.textInputLayout_username); final TextInputLayout textInputLayout_pwd = (TextInputLayout) registerView.findViewById(R.id.textInputLayout_pwd); final EditText editText_dialog_username = textInputLayout_username.getEditText(); final EditText editText_dialog_pwd = textInputLayout_pwd.getEditText(); editText_dialog_username.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (!isChinese(s.toString())) { textInputLayout_username.setErrorEnabled(true); textInputLayout_username.setError("用户名必须是中文!"); flag_username = false; } else { if (s.length() > 4) { textInputLayout_username.setErrorEnabled(true); textInputLayout_username.setError("文字不可以超过4个!"); flag_username = false; } else { textInputLayout_username.setErrorEnabled(false); flag_username = true; } } } }); editText_dialog_pwd.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (!isPwd(s.toString())) { textInputLayout_pwd.setErrorEnabled(true); textInputLayout_pwd.setError("密码必须是6位数字、字母!"); flag_pwd = false; } else { textInputLayout_pwd.setErrorEnabled(false); flag_pwd = true; } } }); AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setIcon(R.mipmap.ic_class) .setTitle("用户注册") .setView(registerView) .setNegativeButton("取消", null) .setPositiveButton("注册", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String username = editText_dialog_username.getText() + ""; String pwd = editText_dialog_pwd.getText() + ""; if (username.equals("") || "".equals(pwd)) { Toast.makeText(mContext, "信息不可以为空!", Toast.LENGTH_LONG).show(); } if (flag_username && flag_pwd) { Toast.makeText(mContext, username + ":" + pwd, Toast.LENGTH_LONG).show(); } else { Toast.makeText(mContext, "信息输入有误,不可以注册!", Toast.LENGTH_LONG).show(); } } }); builder.show(); } }).show(); break; } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: drawerLayout_main.openDrawer(GravityCompat.START); break; case R.id.action_aboutus: Intent view = new Intent(); view.setClass(this, H5Activity.class); startActivity(view); break; } return super.onOptionsItemSelected(item); } /** * 页面跳转,实现共享元素场景切换动画(转场动画) */ public void startActivity(View view, int position) { // 启动页面跳转 Intent intent = new Intent(); intent.setClass(mContext, DetailActivity.class); intent.putExtra("position", position); //判断系统版本 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { View imageView_item_thumbnail = view.findViewById(R.id.imageView_item_icon); View textView_item_title = view.findViewById(R.id.textView_item_title); View textView_item_teacher = view.findViewById(R.id.textView_item_teacher); // 为当前Activity设置共享元素的场景切换动画 /*获取到转场动画对象全部数据拥有转场效果可用ChangeTransform,仅仅是图片可用ChangeImageTransform*/ Transition transition = new ChangeTransform(); //设置转场时间 transition.setDuration(6000); //设置转场回退时执行相同但反方向的动画 getWindow().setExitTransition(transition); /*获取ActivityOptions对象,调用makeSceneTransitionAnimation方法 * 参数1:上下文 * 参数2:可以是多个Pair * * pair参数解释:参数1,第一个界面被点击控件对象,参数2:第二个界面设置的Transition属性 * * */ ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation( (Activity) mContext, Pair.create(textView_item_title, "text_detail"), Pair.create(textView_item_teacher, "text_teacher"), Pair.create(imageView_item_thumbnail, "banner")); //转化成bundle对象 Bundle bundle = options.toBundle(); //开启activity startActivity(intent, bundle); } else { startActivity(intent); } } /** * 检查是否是中文 * * @param str * @return */ private boolean isChinese(String str) { String regexp = "^[\u4e00-\u9fa5]+"; Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(str); return matcher.matches(); } /** * 检查是否是密码 * * @param str * @return */ private boolean isPwd(String str) { String regexp = "^[0-9a-zA-Z]{6}$"; Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(str); return matcher.matches(); } /** * 按钮按下事件onKeyDown方法此方法兼容Android 1.0到Android 2.1 。也是常规方法 * 2.0或更新版的sdk,重写onBackPressed方法即可 * 因此该方法仅适用于2.0以上版本 */ @Override public void onBackPressed() { //如果菜单打开 if (drawerLayout_main.isDrawerOpen(GravityCompat.START)) { //关闭菜单 drawerLayout_main.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } }
MainActivity部分所有代码都加上了注释,比较值得一提的是转场动画部分,步骤:
获取一个转场动画对象
通过这个对象设置转场执行时间
通过getWindow()设置退出时,显示反方向转场动画,传入转场动画对象。
通过Activity选项调用makeScreneTransionAnimation,返回Activity选项对象,
把Activity选项对象转换为Bundle对象
传入intent中
MainActivity中循环实例化了多个
DummyFragment,看下
DummyFragment的代码
package com.steven.materialdesigncomplex; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; import java.util.Map; public class DummyFragment extends Fragment { //上下文 private Context mContext = null; //reyclerview对象 private RecyclerView recyclerView_fragment; //导航索引 private int tabindex = 0; //每个tab页的数据集合 private List<Map<String, Object>> totalList = new ArrayList<>(); /*通过索引获取实例*/ public static DummyFragment getInstance(int tabindex) { DummyFragment fragment = new DummyFragment(); Bundle bundle = new Bundle(); bundle.putInt("tabindex", tabindex); fragment.setArguments(bundle); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = getActivity(); Bundle bundle = getArguments(); tabindex = bundle.getInt("tabindex"); switch (tabindex) { case 1: case 2: case 3: case 4: totalList = MyApp.loadOutlineData(mContext); break; } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //recyclerview加载子视图第二个参数和第三个参数一定要这样填,否则item显示不全 recyclerView_fragment = (RecyclerView) inflater.inflate(R.layout.fragment_dummy, container, false); return recyclerView_fragment; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); recyclerView_fragment.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); recyclerView_fragment.setAdapter(new MainRecyclerAdapter(mContext, totalList)); } }
这个fragment中是通过MyApp.loadOutlineData(mContext);方法加载的本地数据,代码如下:
//以下代码是为了本案例使用,真实情况下数据应该从网络获取或者从数据库获取。 public static List<Map<String, Object>> loadOutlineData(Context context) { List<Map<String, Object>> list = new ArrayList<>(); // 类型数组Typed-Array资源。以下是类型数组的获取方式。 TypedArray array_title = context.getResources().obtainTypedArray(R.array.arrItemTitle); TypedArray array_teacher = context.getResources().obtainTypedArray(R.array.arrItemTeacher); TypedArray array_desc = context.getResources().obtainTypedArray(R.array.arrItemDesc); TypedArray array_star = context.getResources().obtainTypedArray(R.array.arrItemLevel); TypedArray array_image = context.getResources().obtainTypedArray(R.array.arrItemImage); for (int i = 0; i < array_title.length(); i++) { Map<String, Object> map = new HashMap<>(); map.put("title", array_title.getString(i)); map.put("teacher", array_teacher.getString(i)); map.put("desc", array_desc.getString(i)); map.put("image", array_image.getDrawable(i)); map.put("star", array_star.getString(i)); list.add(map); } return list; }
回到MainActivity中还有一个
PagerAdapter看下里面的代码
package com.steven.materialdesigncomplex; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import java.util.List; public class MyPagerAdapter extends FragmentStatePagerAdapter { //fragment集合 private List<Fragment> list = null; //tab集合 private String[] arrTabTitles = null; public MyPagerAdapter(FragmentManager fm, List<Fragment> list, String[] arrTabTitles) { super(fm); this.list = list; this.arrTabTitles = arrTabTitles; } /** * 每个fragment * * @param position * @return */ @Override public Fragment getItem(int position) { return list.get(position); } /** * fragment数量 * * @return */ @Override public int getCount() { return list.size(); } /** * 每个tab * * @param position * @return */ @Override public CharSequence getPageTitle(int position){ return arrTabTitles[position]; } }
加了注释,几乎没什么特别,唯一注意继承的是
FragmentStatePagerAdapter
除了上面的还有详情页和H5页等,由于篇幅限制,下篇继续。。。。
相关文章推荐
- Material Design学习跟随demo解读(二)
- Materail Design学习跟随demo解读(三)
- Demo0 Material Design学习笔记:基于android studio实现
- cocos2d-x 2.X demo学习笔记 9 ----MotionStreakTest 跟随条纹
- 《js事件探秘》学习——鼠标跟随事件demo
- CEGUI学习笔记一--FirstWindow和FalagardDemo1分析 (转kun(小龙))
- android简单demo学习系例之排版(LinearLayout)[xml-based]
- android简单demo学习系例之菜单实现
- Silverligth 学习笔记,demo网站
- 学习OGRE制作简单人物行走demo(一)
- jasperreport中的demo学习
- jquery.Validation.js 学习笔记 [待更新](API 和 DEMO等)
- android简单demo学习系例之按钮
- android简单demo学习系例之排版(TableLayout)[xml-based]
- 网上看到的不错的SQL行列转换的Demo,学习了
- Nutch源代码学习-解读Nutch-运行,爬行过程
- 学习BlogEngine.Net解读笔记系列(一)
- UML活动图学习笔记及Demo
- IbatisNet的使用学习体会(附demo)
- 近日学习Cache,搜集到的一个Demo下载[不断修改、讨论]