前一周基本对整个warmshower的实现有了初步了解,整个项目还是有许多值得学习的地方。准备从活动入手实现代码
第一步实现主要的基础布局,标签栏以及侧边栏及其切换
标签栏利用toolbar实现
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
app:theme="@style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
</android.support.v7.widget.Toolbar>
</merge>
<merge/>标签在UI的结构优化中起着非常重要的作用,它可以删减多余的层级,优化UI。
<merge/>多用于替换FrameLayout或者当一个布局包含另一个时,
<merge/>标签消除视图层次结构中多余的视图组。例如你的主布局文件是垂直布局,引入了一个垂直布局的include,这是如果include布局使用的LinearLayout就没意义了,使用的话反而减慢你的UI表现。这时可以使用<merge/>标签优化。
记得在application中申明@style/wsAppTheme
侧边栏布局 navigation_drawer.xml
<?xml version="1.0" encoding="utf-8"?><!-- navigation drawer -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_gravity="left|start"
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent"
android:clickable="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="230dp"
android:background="#FF777777">
<ImageView
android:id="@+id/imgUserPhoto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/default_hostinfo_profile"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="bottom"
android:paddingBottom="14dp"
android:paddingTop="14dp"
android:background="#CC555555">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="You are not logged in. Use the Account/Login selection below."
android:id="@+id/lblNotLoggedIn"
android:layout_marginLeft="16dp"
android:visibility="gone" />
<TextView
android:id="@+id/lblUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/WsPictureOverlayTitle.Medium"
android:text="Username"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/lblFullname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/WsPictureOverlayTitle"
android:text="user@email.com"/>
</LinearLayout>
</RelativeLayout>
<ListView
android:id="@+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="#ffffff" />
</LinearLayout>
</RelativeLayout>
</merge>
没什么可讲
利用toolbar drawerlayout实现侧边栏
新建一个WSBaseActivity 所有的侧滑栏下的activity都继承自Baseactivity,Baseactivity实现功能:侧换栏切换与登录验证
首先实现侧边栏切换
为了实现模块及通用性
新建NavRow实现侧滑栏菜单管理
public class NavRow {
int mIconResource;
String mRowText;
String mOnClickAction;
public NavRow(int iconResourceId, String rowText, String onClickAction) {
this.mIconResource = iconResourceId;
this.mRowText = rowText;
this.mOnClickAction = onClickAction;
}
public int getIconResource() {
return mIconResource;
}
public String getRowText() {
return mRowText;
}
public String getOnClickAction() {
return mOnClickAction;
}
}
baseactivity 继承自 AppCompatActivity
AppCompatActivity参考 http://blog.csdn.net/wsdssss/article/details/51276379
在value文件夹新建array保存侧换栏图标和文字,好处就是有利于管理
<!-- Translatable text of Navigation Drawer Menu -->
<string-array name="nav_menu_options">
<item >Map</item>
<item >Favorites</item>
<item >Messages</item>
<item >Account/LogIn</item>
<item >Settings</item>
<item >About</item>
</string-array>
<string-array name="nav_menu_activities" translatable="false">
<item>Maps2Activity</item>
<item>StarredHostTabActivity</item>
<item>MessagesTabActivity</item>
<item>AuthenticatorActivity</item>
<item>SettingsActivity</item>
<item>AboutActivity</item>
</string-array>
<string-array name="nav_menu_icons" translatable="false">
<item>@drawable/ic_map_grey600_24dp</item>
<item>@drawable/ic_favorite_grey600_24dp</item>
<item>@drawable/ic_message_grey600_24dp</item>
<item>@drawable/ic_login_grey600_24dp</item>
<item>@drawable/ic_settings_grey600_24dp</item>
<item>@drawable/ic_help_grey600_24dp</item>
<item>@drawable/ic_info_grey600_24dp</item>
</string-array>
而且如果软件支持多种语言的化直接不同的语言建立不同的array文件即可。
public class WSBaseActivity extends AppCompatActivity implements View.OnClickListener {
public static final String TAG = "WSBaseActivity";
protected String mActivityName = this.getClass().getSimpleName();
protected Toolbar mToolbar;
protected DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private ListView mLeftDrawerList;
//private NavDrawerListAdapter mNavDrawerListAdapter;
private int mCurrentActivity;
protected ArrayList<NavRow> mNavRowList = new ArrayList<NavRow>();
String mActivityFriendly;//toolbar标题
protected boolean mHasBackIntent = false;
protected boolean mDisableNavigation = false;
/**
* 实现侧滑栏 图标 文字 activity之间的同步
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] navMenuOptions = getResources().getStringArray(R.array.nav_menu_options);
String[] navMenuActivities = getResources().getStringArray(R.array.nav_menu_activities);
HashMap<String, String> mActivityClassToFriendly = new HashMap<String, String>();
TypedArray icons = getResources().obtainTypedArray(R.array.nav_menu_icons);
for (int i = 0; i < navMenuOptions.length; i++) {
mActivityClassToFriendly.put(navMenuActivities[i], navMenuOptions[i]);
int icon = icons.getResourceId(i, R.drawable.ic_action_email);
NavRow row = new NavRow(icon, navMenuOptions[i], navMenuActivities[i]);
mNavRowList.add(row);
if (navMenuActivities[i].equals(mActivityName)) {
mCurrentActivity = i;
}
}
mActivityFriendly = mActivityClassToFriendly.get(mActivityName);
}
protected boolean initView() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mLeftDrawerList = (ListView) mDrawerLayout.findViewById(R.id.left_drawer);
mLeftDrawerList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mNavDrawerListAdapter = new NavDrawerListAdapter(this, mNavRowList, mCurrentActivity);
mLeftDrawerList.setAdapter(mNavDrawerListAdapter);
mLeftDrawerList.setOnItemClickListener(this);
if (mToolbar != null) {
mToolbar.setTitle(mActivityFriendly);
setSupportActionBar(mToolbar);
}
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
//用于实现登录验证,后面一大坑
/**
*
// Make sure we have an active account, or go to authentication screen
if (!setupCredentials()) {
return(false);
}
*/
initDrawer();
return true;
}
/**
* 初始化侧滑栏
*/
protected void initDrawer() {
final TextView lblUsername = (TextView) mDrawerLayout.findViewById(R.id.lblUsername);
final TextView lblNotLoggedIn = (TextView) mDrawerLayout.findViewById(R.id.lblNotLoggedIn);
final TextView lblFullname = (TextView) mDrawerLayout.findViewById(R.id.lblFullname);
final ImageView memberPhoto = (ImageView) mDrawerLayout.findViewById(R.id.imgUserPhoto);
//实现侧滑栏显示用户,暂时注释掉,后面一大坑
/**
*
Host memberInfo = MemberInfo.getMemberInfo();
if (memberInfo != null) {
lblUsername.setText(memberInfo.getName());
lblFullname.setText(memberInfo.getFullname());
String photoPath = MemberInfo.getMemberPhotoFilePath();
if (photoPath != null && memberPhoto != null) {
memberPhoto.setImageBitmap(BitmapFactory.decodeFile(photoPath));
} else {
memberPhoto.setImageResource(R.drawable.default_hostinfo_profile);
}
} else {
memberPhoto.setImageResource(R.drawable.default_hostinfo_profile);
lblNotLoggedIn.setVisibility(View.VISIBLE);
lblUsername.setVisibility(View.GONE);
lblFullname.setVisibility(View.GONE);
}
*/
if (mDisableNavigation)
{
mDrawerToggle.setDrawerIndicatorEnabled(false);
}
}
//activity完全执行之后回调
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
if (mHasBackIntent) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
/**
* 你可能希望当一种或者多种配置改变时避免重新启动你的activity。当这些配置改变时不会重新启动activity,而会调用activity的
onConfigurationChanged(Resources.Configuration)方法。
* @param newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
/**
* android中的后退键
*/
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawers();
return;
}
if (mDisableNavigation) {
return;
}
super.onBackPressed();
}
/*
/**
* Activity 从 Pause 状态转换到 Active 状态时被调用。
@Override
protected void onResume() {
super.onResume();
if (!setupCredentials()) {
return;
}
initDrawer();
}
*/
/**
* 如果你想在Activity中得到新打开Activity关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent,int requestCode)
* 方法打开新的Activity,新的Activity关闭后会向前面的Activity传回数据,为了得到传回的数据,你必须在前面的Activity中重写onActivityResult
* (int requestCode, int resultCode,Intent data)方法
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Update the drawer if we're returning from another activity
initDrawer();
}
/**
* Handle click from ListView in NavigationDrawer
*
* @param parent
* @param view
* @param position
* @param id
*/
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String[] activities = getResources().getStringArray(R.array.nav_menu_activities);
if (mActivityName.equals(activities[position])) return;
try {
Class activityClass = Class.forName(this.getPackageName() + ".activity." + activities[position]);
Intent i = new Intent(this, activityClass);
startActivity(i);
} catch (ClassNotFoundException e) {
Log.i(TAG, "Class not found: " + activities[position]);
}
mDrawerLayout.closeDrawers();
}
/**
* @return true if we already have an account set up in the AccountManager
* false if we have to wait for the auth screen to process
*/
/*
public boolean setupCredentials() {
try {
AuthenticationHelper.getWarmshowersAccount();
if (MemberInfo.getInstance() == null) {
MemberInfo.initInstance(null); // Try to get persisted information
}
return true;
} catch (NoAccountException e) {
if (this.getClass() != AuthenticatorActivity.class) { // Would be circular, so don't do it.
Intent i = new Intent(this, AuthenticatorActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);
}
return false;
}
}
*/
}
NavDrawerListAdapter.javapublic class NavDrawerListAdapter extends ArrayAdapter<NavRow> { private final Context mContext; private final ArrayList<NavRow> mValues; private final int mCurrentActivityIndex; public NavDrawerListAdapter(Context context, ArrayList<NavRow> values, int currentActivity) { super(context, R.layout.nav_drawer_row, values); mContext = context; mValues = values; mCurrentActivityIndex = currentActivity; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rowView = inflater.inflate(R.layout.nav_drawer_row, parent, false); TextView menuTextView = (TextView) rowView.findViewById(R.id.menu_text); ImageView iconView = (ImageView) rowView.findViewById(R.id.icon); NavRow currentRow = mValues.get(position); menuTextView.setText(currentRow.getRowText()); iconView.setImageResource(currentRow.getIconResource()); if (position == mCurrentActivityIndex) { rowView.setBackgroundColor(Application.this.getResources().getColor(R.color.backgroundLightGrey)); } //WSAndroidApplication.getAppContext() return rowView; } }