屏幕适配
1.环境的搭建
2.ActionBar的显示
1.Android 文档镜像:http://wear.techbrood.com
2.3.0以后才有,为了向下兼容,引用v7-appcompat,v7为一个library工程,直接导入,关联
3.jar包不能提供布局和图片等资源
步骤:
(1). 引用v7-appcompat
(2). Activity继承ActionBarActivity
(3). android:theme="@style/Theme.AppCompat.Light"
3.ActionBar 搜索
public class MainActivity extends ActionBarActivity implements OnQueryTextListener
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
yourapp:showAsAction="ifRoom"
yourapp:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
2.处理ActionBar上的按钮事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
case R.id.action_settings:
openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
3.实现搜索功能,查看android API demo
4.搜索功能
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
yourapp:showAsAction="ifRoom"
yourapp:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
@SuppressLint("NewApi")
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// 如果运行的环境 (部署到什么版本的手机 )大于3.0
if (android.os.Build.VERSION.SDK_INT > 11) {
SearchView searchView = (SearchView) menu.findItem(
R.id.action_search).getActionView();
searchView.setOnQueryTextListener(this);// 搜索的监听
}
return true;
}
3.
// 当搜索提交的时候
@Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(getApplicationContext(), query, 0).show();
return true;
}
// 当搜索的文本发生变化
@Override
public boolean onQueryTextChange(String newText) {
return true;
}
5.actionBar 返回按钮的处理
2.点击actionbar图标返回上一个Activity
<activity android:name=".DetailActivity"
android:label="@string/app_detail"
android:parentActivityName="com.itheima.googleplay.MainActivity"
>
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.itheima.googleplay.MainActivity" />
</activity>
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
让每一个Activity的ActionBar的标题不一样,在Activity中的配置文件中配置独立的label
android:label=""
6.给actionbar添加tab标签
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- STATES WHEN BUTTON IS NOT PRESSED -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/tab_unselected" />
<item android:state_focused="false" android:state_selected="true"
android:state_pressed="false"
android:drawable="@drawable/tab_selected" />
<!-- Focused states (such as when focused with a d-pad or mouse hover) -->
<item android:state_focused="true" android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/tab_unselected_focused" />
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="false"
android:drawable="@drawable/tab_selected_focused" />
<!-- STATES WHEN BUTTON IS PRESSED -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false"
android:state_pressed="true"
android:drawable="@drawable/tab_unselected_pressed" />
<item android:state_focused="false" android:state_selected="true"
android:state_pressed="true"
android:drawable="@drawable/tab_selected_pressed" />
<!-- Focused states (such as when focused with a d-pad or mouse hover) -->
<item android:state_focused="true" android:state_selected="false"
android:state_pressed="true"
android:drawable="@drawable/tab_unselected_pressed" />
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="true"
android:drawable="@drawable/tab_selected_pressed" />
</selector>
3.实现自定义主题
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@style/Theme.AppCompat.Light">
<item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
<!-- Support library compatibility -->
<item name="actionBarTabStyle">@style/MyActionBarTabs</item>
</style>
<!-- ActionBar tabs styles -->
<style name="MyActionBarTabs"
parent="@style/Widget.AppCompat.ActionBar.TabView">
<!-- tab indicator -->
<item name="android:background">@drawable/actionbar_tab_indicator</item>
<!-- Support library compatibility -->
<item name="background">@drawable/actionbar_tab_indicator</item>
</style>
</resources>
3.1. 在清单文件中添加使用该主题
4.在代码里添加标签
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab1=actionBar.newTab().setText("标签一").setTabListener(new MyTabListener());
actionBar.addTab(tab1);
5.详情见文档和官网7.抽屉&抽屉的开关
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/dl"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!--如果抽屉没有打开 会显示线性布局 -->
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</LinearLayout>
<!-- 左面可以滑出来一个抽屉 -->
<!--
<RelativeLayout
android:layout_gravity="left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000">
</RelativeLayout> -->
<RelativeLayout
android:layout_gravity="right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00">
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
(2)代码
public class MainActivity extends Activity {
DrawerLayout drawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout=(DrawerLayout) findViewById(R.id.dl);
drawerLayout.openDrawer(Gravity.RIGHT);// 打开左面抽屉
drawerLayout.setDrawerListener(new DrawerListener() {
@Override
public void onDrawerStateChanged(int arg0) {
}
@Override
public void onDrawerSlide(View arg0, float arg1) {
}
@Override
public void onDrawerOpened(View arg0) {
}
@Override
public void onDrawerClosed(View arg0) {
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
2.与ActionBar关联,完整步骤笔记
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
drawerToggle = new ActionBarDrawerToggle(this,
mDrawerLayout, R.drawable.ic_drawer_am, R.string.open_drawer,
R.string.close_drawer){
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
Toast.makeText(getApplicationContext(), "抽屉关闭了", 0).show();
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
Toast.makeText(getApplicationContext(), "抽屉打开了", 0).show();
}
};
mDrawerLayout.setDrawerListener(drawerToggle);
// 让开关和actionbar建立关系
drawerToggle.syncState();
/** 处理actionBar菜单条目的点击事件 */
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_search) {
Toast.makeText(getApplicationContext(), "搜索", 0).show();
}
return drawerToggle.onOptionsItemSelected(item)|super.onOptionsItemSelected(item);
}
9.ViewPager 切换界面&和Tab标签建立关系
与ActionBar的Tab建立关系,每个Pager用Fragment代替,
private class MainAdpater extends FragmentStatePagerAdapter{
public MainAdpater(FragmentManager fm) {
super(fm);
}
// 每个条目返回的fragment
// 0
@Override
public Fragment getItem(int position) {
// 通过Fragment工厂 生产Fragment
return FragmentFactory.createFragment(position);
}
// 一共有几个条目
@Override
public int getCount() {
return tab_names.length;
}
// 返回每个条目的标题
@Override
public CharSequence getPageTitle(int position) {
return tab_names[position];
}
}
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
}
@Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
}
};
滑动ViewPager时Tab改变,监听ViewPager的滑动
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
//当viewPager页面发生改变时调用
public void onPageSelected(int position){
super.onPageSelected(position);
getSupportActionBar().setSelsectNavigationItem(position);
}
});
10.使用ViewPager中自带的pagerTabStrip 切换
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
>
<android.support.v4.view.PagerTabStrip
android:id="@+id/pager_tab_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#ffffff"
android:textColor="#000"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>
(2)
private class MainAdpater extends FragmentStatePagerAdapter{
public MainAdpater(FragmentManager fm) {
super(fm);
}
// 每个条目返回的fragment
// 0
@Override
public Fragment getItem(int position) {
if(position==0){
return new HomeFragment();
}else{
return new AppFragment();
}
}
// 一共有几个条目
@Override
public int getCount() {
return 4;
}
// 返回每个条目的标题
@Override
public CharSequence getPageTitle(int position) {
return "标签"+position;
}
}
</span>
(3)设置下划线颜色
pager_tab_strip=(PagerTabStrip) findViewById(R.id.pager_tab_strip);
// 设置标签下划线的颜色
pager_tab_strip.setTabIndicatorColor(getResources().getColor(R.color.indicatorcolor));
(4)使用适配器
11.抽取BaseActivity
两个或以上Activity时,提取共性
(1)简版
public class BaseActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
initView();
initActionBar();
}
protected void initActionBar() {
}
protected void initView() {
}
protected void init() {
}
}
(2)管理所有activity,方便退出,有两种方法,1.把所有Activity放在集合中管理 2.每个Activity创建一个广播接收者
/**
* 抽取BaseActivity 管理所有activity 方便退出
* @author itcast
*
*/
public class BaseActivity extends ActionBarActivity {
// 管理运行的所有的activity
public final static List<BaseActivity> mActivities = new LinkedList<BaseActivity>();
// private KillAllReceiver receiver;
// private class KillAllReceiver extends BroadcastReceiver{
//
// @Override
// public void onReceive(Context context, Intent intent) {
// finish();
// }
// }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// receiver=new KillAllReceiver();
// IntentFilter filter=new IntentFilter("com.itheima.google.killall");
// registerReceiver(receiver, filter);
synchronized (mActivities) {
mActivities.add(this);
}
init();
initView();
initActionBar();
}
@Override
protected void onDestroy() {
super.onDestroy();
synchronized (mActivities) {
mActivities.remove(this);
}
// if(receiver!=null){
// unregisterReceiver(receiver);
// receiver=null;
// }
}
public void killAll() {
// 复制了一份mActivities 集合
List<BaseActivity> copy;
synchronized (mActivities) {
copy = new LinkedList<BaseActivity>(mActivities);
}
for (BaseActivity activity : copy) {
activity.finish();
}
// 杀死当前的进程
android.os.Process.killProcess(android.os.Process.myPid());
}
protected void initActionBar() {
}
protected void initView() {
}
protected void init() {
}
}
12.Fragment的切换
<resources>
<string name="app_name">GooglePlay</string>
<string name="menu_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="action_search">搜索</string>
<string name="app_detail">应用详情</string>
<string name="open_drawer">抽屉打开了</string>
<string name="close_drawer">抽屉关闭了</string>
<string name="load_error">加载失败,点击重试</string>
<string-array name="tab_names">
<item>首页</item>
<item>应用</item>
<item>游戏</item>
<item>专题</item>
<item>分类</item>
<item>排行</item>
</string-array>
</resources>
使用
tab_names= getResources().getStringArray(R.array.tab_names);
/**
* 代表当前应用程序
* @author itcast
*
*/
public class BaseApplication extends Application {
private static BaseApplication application;
@Override
public void onCreate() {
super.onCreate();
application=this;
}
public static Context getApplication() {
return application;
}
}
(2)需要在清单文件中添加
android:name="BaseApplication"
(3)使用,不需要传递Context,调用getResource
public class Uiutils {
public static Resources getResource() {
return BaseApplication.getApplication().getResources();
}
public static Context getContext(){
return BaseApplication.getApplication();
}
/** dip转换px */
public static int dip2px(int dip) {
final float scale = getResource().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f);
}
/** pxz转换dip */
public static int px2dip(int px) {
final float scale = getResource().getDisplayMetrics().density;
return (int) (px / scale + 0.5f);
}
}
(4)在程序中使用
File filesDir = Uiutils.getContext().getCacheDir(); // cache getFileDir file
13.Fragment工厂
public class FragmentFactory {
private static Map<Integer, Fragment> mFragments = new HashMap<Integer, Fragment>();
public static Fragment createFragment(int position) {
Fragment fragment = null;
fragment = mFragments.get(position); //在集合中取出来Fragment
if (fragment == null) { //如果再集合中没有取出来 需要重新创建
if (position == 0) {
fragment = new HomeFragment();
} else if (position == 1) {
fragment = new AppFragment();
} else if (position == 2) {
fragment = new GameFragment();
} else if (position == 3) {
fragment = new SubjectFragment();
} else if (position == 4) {
fragment = new CategoryFragment();
} else if (position == 5) {
fragment = new TopFragment();
}
if (fragment != null) {
mFragments.put(position, fragment);// 把创建好的Fragment存放到集合中缓存起来
}
}
return fragment;
}
}
2.切换
private class MainAdpater extends FragmentStatePagerAdapter{
public MainAdpater(FragmentManager fm) {
super(fm);
}
// 每个条目返回的fragment
// 0
@Override
public Fragment getItem(int position) {
// 通过Fragment工厂 生产Fragment
return FragmentFactory.createFragment(position);
}
// 一共有几个条目
@Override
public int getCount() {
return tab_names.length;
}
// 返回每个条目的标题
@Override
public CharSequence getPageTitle(int position) {
return tab_names[position];
}
}
12.LogUtils
public class LogUtils {
/** 日志输出级别NONE */
public static final int LEVEL_NONE = 0;
/** 日志输出级别V */
public static final int LEVEL_VERBOSE = 1;
/** 日志输出级别D */
public static final int LEVEL_DEBUG = 2;
/** 日志输出级别I */
public static final int LEVEL_INFO = 3;
/** 日志输出级别W */
public static final int LEVEL_WARN = 4;
/** 日志输出级别E */
public static final int LEVEL_ERROR = 5;
/** 日志输出时的TAG */
private static String mTag = "googleplay";
/** 是否允许输出log */
private static int mDebuggable = LEVEL_ERROR;
/** 用于记时的变量 */
private static long mTimestamp = 0;
/** 以级别为 d 的形式输出LOG */
public static void v(String msg) {
if (mDebuggable >= LEVEL_VERBOSE) {
Log.v(mTag, msg);
}
}
/** 以级别为 d 的形式输出LOG */
public static void d(String msg) {
if (mDebuggable >= LEVEL_DEBUG) {
Log.d(mTag, msg);
}
}
/** 以级别为 i 的形式输出LOG */
public static void i(String msg) {
if (mDebuggable >= LEVEL_INFO) {
Log.i(mTag, msg);
}
}
/** 以级别为 w 的形式输出LOG */
public static void w(String msg) {
if (mDebuggable >= LEVEL_WARN) {
Log.w(mTag, msg);
}
}
/** 以级别为 w 的形式输出Throwable */
public static void w(Throwable tr) {
if (mDebuggable >= LEVEL_WARN) {
Log.w(mTag, "", tr);
}
}
/** 以级别为 w 的形式输出LOG信息和Throwable */
public static void w(String msg, Throwable tr) {
if (mDebuggable >= LEVEL_WARN && null != msg) {
Log.w(mTag, msg, tr);
}
}
/** 以级别为 e 的形式输出LOG */
public static void e(String msg) {
if (mDebuggable >= LEVEL_ERROR) {
Log.e(mTag, msg);
}
}
/** 以级别为 e 的形式输出Throwable */
public static void e(Throwable tr) {
if (mDebuggable >= LEVEL_ERROR) {
Log.e(mTag, "", tr);
}
}
/** 以级别为 e 的形式输出LOG信息和Throwable */
public static void e(String msg, Throwable tr) {
if (mDebuggable >= LEVEL_ERROR && null != msg) {
Log.e(mTag, msg, tr);
}
}
/** 以级别为 e 的形式输出msg信息,附带时间戳,用于输出一个时间段结束点* @param msg 需要输出的msg */
public static void elapsed(String msg) {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - mTimestamp;
mTimestamp = currentTime;
e("[Elapsed:" + elapsedTime + "]" + msg);
}
}
15.显示界面的架子
public class HomeFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FrameLayout frameLayout=new FrameLayout(getActivity());
init(); // 在FrameLayout中 添加4种不同的界面
showPage();// 根据不同的状态显示不同的界面
show();// 根据服务器的数据 切换状态
return frameLayout;
}
16.4种界面&五种状态
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<ImageView
android:id="@+id/page_iv"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:scaleType="centerInside"
android:src="@drawable/ic_error_page" />
<Button
android:id="@+id/page_bt"
android:layout_width="wrap_content"
android:layout_height="34dp"
android:layout_below="@id/page_iv"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@drawable/btn_bg"
android:ellipsize="end"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:singleLine="true"
android:text="加载失败,点击重试"
android:textColor="#ff717171"
android:textSize="14dp" />
</RelativeLayout>
</FrameLayout>
//加载界面, 在FrameLayout中 添加4种不同的界面
private View loadingView;// 加载中的界面
private View errorView;// 错误界面
private View emptyView;// 空界面
private View successView;// 加载成功的界面
private FrameLayout frameLayout;
// 在FrameLayout中 添加几种不同的界面
private void init() {
loadingView = createLoadingView(); // 创建了加载中的界面
if (loadingView != null) {
frameLayout.addView(loadingView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
errorView = createErrorView(); // 加载错误界面
if (errorView != null) {
frameLayout.addView(errorView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
emptyView = createEmptyView(); // 加载空的界面
if (emptyView != null) {
frameLayout.addView(emptyView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
showPage();// 根据不同的状态显示不同的界面
}
//创建界面
/* 创建了空的界面 */
private View createEmptyView() {
View view = View.inflate(getActivity(), R.layout.loadpage_empty, null);
return view;
}
/* 创建了错误界面 */
private View createErrorView() {
View view = View.inflate(getActivity(), R.layout.loadpage_error, null);
return view;
}
/* 创建加载中的界面 */
private View createLoadingView() {
View view = View
.inflate(getActivity(), R.layout.loadpage_loading, null);
return view;
}
4.根据不同的状态显示不同的界面---五种状态showPage();
// 根据不同的状态显示不同的界面---五种状态showPage();
public static final int STATE_UNKOWN = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_ERROR = 2;
public static final int STATE_EMPTY = 3;
public static final int STATE_SUCCESS = 4;
public static int state = STATE_UNKOWN; //当前状态
// 根据不同的状态显示不同的界面
private void showPage() {
if (loadingView != null) {
loadingView.setVisibility(state == STATE_UNKOWN
|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
}
if (errorView != null) {
errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE
: View.INVISIBLE);
}
if (emptyView != null) {
emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE
: View.INVISIBLE);
}
}
5.总结
public class HomeFragment extends Fragment {
public static final int STATE_UNKOWN = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_ERROR = 2;
public static final int STATE_EMPTY = 3;
public static final int STATE_SUCCESS = 4;
public static int state = STATE_UNKOWN;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
frameLayout = new FrameLayout(getActivity());
init(); // 在FrameLayout中 添加4种不同的界面
showPage();// 根据不同的状态显示不同的界面
show();// 根据服务器的数据 切换状态
return frameLayout;
}
private View loadingView;// 加载中的界面
private View errorView;// 错误界面
private View emptyView;// 空界面
private View successView;// 加载成功的界面
private FrameLayout frameLayout;
// 添加4种不同界面
private void init() {
loadingView = createLoadingView(); // 创建了加载中的界面
if (loadingView != null) {
frameLayout.addView(loadingView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
errorView = createErrorView(); // 加载错误界面
if (errorView != null) {
frameLayout.addView(errorView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
emptyView = createEmptyView(); // 加载空的界面
if (emptyView != null) {
frameLayout.addView(emptyView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
showPage();// 根据不同的状态显示不同的界面
}
// 根据不同的状态显示不同的界面
private void showPage() {
if (loadingView != null) {
loadingView.setVisibility(state == STATE_UNKOWN
|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
}
if (errorView != null) {
errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE
: View.INVISIBLE);
}
if (emptyView != null) {
emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE
: View.INVISIBLE);
}
}
// 根据服务器的数据切换状态
private void show() {
}
//创建界面
private View createEmptyView() {
View view = View.inflate(getActivity(), R.layout.loadpage_empty, null);
return view;
}
private View createErrorView() {
View view = View.inflate(getActivity(), R.layout.loadpage_error, null);
return view;
}
private View createLoadingView() {
View view = View
.inflate(getActivity(), R.layout.loadpage_loading, null);
return view;
}
}
17.根据状态切换界面
1.根据服务器的数据 切换状态
(1)枚举
// 根据服务器的数据 切换状态
//服务器总共会返回三种状态,用枚举来保存
public enum LoadResult {
error(2), empty(3), success(4);
int value;
LoadResult(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
(2)根据服务器的数据 切换状态,模拟联网,所以睡2秒
//show()
// 根据服务器的数据 切换状态
private void show() {
if (state == STATE_ERROR || state == STATE_EMPTY) {
state = STATE_LOADING;
}
// 请求服务器 获取服务器上数据 进行判断
// 请求服务器 返回一个结果
//请求服务器 在子线程中执行,但改变界面需要在主线程中执行,所以使用runOnUiThread
new Thread() {
public void run() {
SystemClock.sleep(2000);
final LoadResult result = load();
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (result != null) {
state = result.getValue();
showPage(); // 状态改变了,重新判断当前应该显示哪个界面
}
}
});
}
};
}.start();
showPage();
}
private LoadResult load() {
return LoadResult.success;
}
(3)点击错误界面中的按钮,再连网一遍
Button page_bt = (Button) view.findViewById(R.id.page_bt);
page_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
show();
}
});
2.总结
public class HomeFragment extends Fragment {
public static final int STATE_UNKOWN = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_ERROR = 2;
public static final int STATE_EMPTY = 3;
public static final int STATE_SUCCESS = 4;
public static int state = STATE_UNKOWN;//当前状态
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (frameLayout == null) { // 之前的frameLayout 已经记录了一个爹了 爹是之前的ViewPager
frameLayout = new FrameLayout(getActivity());
init(); // 在FrameLayout中 添加4种不同的界面
}else{
ViewUtils.removeParent(frameLayout);// 移除frameLayout之前的爹
}
show();// 根据服务器的数据 切换状态
// 先干掉之前的爹
return frameLayout; // 拿到当前viewPager 添加这个framelayout
}
private View loadingView;// 加载中的界面
private View errorView;// 错误界面
private View emptyView;// 空界面
private View successView;// 加载成功的界面
private FrameLayout frameLayout;
// 在FrameLayout中 添加几种不同的界面
private void init() {
loadingView = createLoadingView(); // 创建了加载中的界面
if (loadingView != null) {
frameLayout.addView(loadingView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
errorView = createErrorView(); // 加载错误界面
if (errorView != null) {
frameLayout.addView(errorView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
emptyView = createEmptyView(); // 加载空的界面
if (emptyView != null) {
frameLayout.addView(emptyView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
showPage();// 根据不同的状态显示不同的界面
}
// 根据不同的状态显示不同的界面
private void showPage() {
if (loadingView != null) {
loadingView.setVisibility(state == STATE_UNKOWN
|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
}
if (errorView != null) {
errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE
: View.INVISIBLE);
}
if (emptyView != null) {
emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE
: View.INVISIBLE);
}
if (state == STATE_SUCCESS) {
successView = createSuccessView();
if (successView != null) {
frameLayout.addView(successView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
successView.setVisibility(View.VISIBLE);
}
}
}
private View createSuccessView() {
TextView tv = new TextView(getActivity());
tv.setText("加载成功了....");
tv.setTextSize(30);
return tv;
}
public enum LoadResult {
error(2), empty(3), success(4);
int value;
LoadResult(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
// 根据服务器的数据 切换状态
private void show() {
if (state == STATE_ERROR || state == STATE_EMPTY) {
state = STATE_LOADING;
}
// 请求服务器 获取服务器上数据 进行判断
// 请求服务器 返回一个结果
new Thread() {
public void run() {
SystemClock.sleep(2000);
final LoadResult result = load();
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (result != null) {
state = result.getValue();
showPage(); // 状态改变了,重新判断当前应该显示哪个界面
}
}
});
}
};
}.start();
showPage();
}
private LoadResult load() {
return LoadResult.success;
}
/* 创建了空的界面 */
private View createEmptyView() {
View view = View.inflate(getActivity(), R.layout.loadpage_empty, null);
return view;
}
/* 创建了错误界面 */
private View createErrorView() {
View view = View.inflate(getActivity(), R.layout.loadpage_error, null);
Button page_bt = (Button) view.findViewById(R.id.page_bt);
page_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
show();
}
});
return view;
}
/* 创建加载中的界面 */
private View createLoadingView() {
View view = View
.inflate(getActivity(), R.layout.loadpage_loading, null);
return view;
}
}
18.复用frameLayout bug的解决
1.创建成功界面
if (state == STATE_SUCCESS) {
successView = createSuccessView();
if (successView != null) {
frameLayout.addView(successView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
successView.setVisibility(View.VISIBLE);
}
}
private View createSuccessView() {
TextView tv = new TextView(getActivity());
tv.setText("加载成功了....");
tv.setTextSize(30);
return tv;
}
2.加上
if(frameLayout==null){
frameLayout = new FrameLayout(getActivity());
init(); // 在FrameLayout中 添加4种不同的界面
}
报错
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
ViewPager会自动加载三个页面的信息,把Pager回收掉但frameLayout还在内存中
解决方法:先移除之前的爹
写一个工具类,见下
public class ViewUtils {
public static void removeParent(View v){
// 先找到爹 在通过爹去移除孩子
ViewParent parent = v.getParent();
//所有的控件 都有爹 爹一般情况下 就是ViewGoup
if(parent instanceof ViewGroup){
ViewGroup group=(ViewGroup) parent;
group.removeView(v);
}
}
}
2.判断
if (frameLayout == null) { // 之前的frameLayout 已经记录了一个爹了 爹是之前的ViewPager
frameLayout = new FrameLayout(getActivity());
init(); // 在FrameLayout中 添加4种不同的界面
}else{
ViewUtils.removeParent(frameLayout);// 移除frameLayout之前的爹
}
show();// 根据服务器的数据 切换状态
// 先干掉之前的爹
return frameLayout; // 拿到当前viewPager 添加这个framelayout