您的位置:首页 > 其它

简单仿魅族手机Setings界面设计

2015-10-12 16:38 399 查看
最近不是很忙,想起半年前,在上家公司的一件事,公司要做一套全新的UI界面 ,其中我被分配到锁屏界面的UI设计,当时刚入android第二年,过程自然懂的都懂,不过幸好平时没懒散 ,最终圆满的完成了。 不过呢,我的另外一位同事分到一个任务,就是仿魅族手机的Settings界面(但是没有完成
-.-!),其实在很早的时候 ,我就向公司提出做这个设计(我不知道当时魅族有没有做这个),后来公司没重视我的提议,所以就作废了,哎,公司的悲哀~ 今天我想来自己试试,毕竟当时自己提过的事情 ,自己还是要完成一下的。大致看下界面(公司的网,只能做到这样)



那么,我们做之前考虑几个问题:

1、首先提到Fragment,在Android中,最能体现Fragment用处的是哪里 呢,当然就是Setings界面,其实看过平板的人都知道 ,Fragment就是为了这个设计的。 OK,这样就明白的Settings界面的内容就是通过Fragment来切换的,所以我们自己做的例子中肯定要用到Fragment来做到界面内容的切换。 如果不清楚用法可以参考 : http://blog.csdn.net/lmj623565791/article/details/37970961

2、再一个问题,我们怎么去定义一个ViewGroup来实现左右滑动,而且做到没有滑动冲突 ,这个问题嘛,其实我们最好是用系统的控件 ,这样或许可以省很多事情 ,这里我选HorizontalScrollView,我相信Google设计控件的时候 ,自己肯定也对这个冲突做过处理,OK,讲了这么多,就是为了准备工作,今天就来玩一把~

直观的看,界面有两个部分,第一个部分就是左边的menu,它控制右边的显示 ,第二个部分就是content , 它负责显示,先看布局

activity_main.xml

<com.example.horizontalscrollview_01.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
 
<LinearLayout
android:id="@+id/wrapper"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
 
<FrameLayout
android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="match_parent" 
android:background="#ee1234">
</FrameLayout>
 
<FrameLayout
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="match_parent" 
android:background="#44ee45">
</FrameLayout>
</LinearLayout>
 
</com.example.horizontalscrollview_01.SlidingMenu>


如果 我们把两个Framelayout的layout_width都改为固定值(例如200dp)的话,就可以清楚的看到



当然这个效果需要在自定义的控件中动态的控制 ,说了这么多,看下吧
SlidingMenu.java

package com.example.horizontalscrollview_01;
 
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
 
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
 
public class SlidingMenu extends HorizontalScrollView {
private LinearLayout mWrapper;
private FrameLayout mMenu;
private FrameLayout mContent;
private int mScreenWidth;
private Context mContext;
 
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
 
public SlidingMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
 
public SlidingMenu(Context context) {
this(context, null);
}
 
private void init(Context context) {
mContext = context;
WindowManager wm = (WindowManager) mContext
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
// 获取屏幕的宽
mScreenWidth = outMetrics.widthPixels;
 
}
 
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mWrapper = (LinearLayout) getChildAt(0);
mMenu = (FrameLayout) mWrapper.getChildAt(0);
mContent = (FrameLayout) mWrapper.getChildAt(1);
}
 
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//这里确定两个区域的宽度
mMenu.getLayoutParams().width = mScreenWidth;
mContent.getLayoutParams().width = mScreenWidth * 4 / 5;
}
 
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
}
 
@SuppressLint("NewApi")
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
//在滑动的时候,让menu区域一直在屏幕的左边
mMenu.scrollTo(-l, 0);
}
 
}


在onMeasure中决定了menu和content的宽度,如果我们不要onScrollChaged,我们把这个布局放到activity中,那么就是原始的HorizontalScrollView效果,现在我们在onScrollChanged中,让它在滑动的过程中,始终让menu处于屏幕的起始位置,这个 l 参数其实就是getScrollX(),至于这里为什么是 -l ,参见我之前的博客  Android 之Scroller的理解与应用 ,这里就不多说了。

大致布局已经OK了,现在我们在menu和content区域加入Fragment ,首先创建两个Fragment。
先看menu区域的

menu_fragment.xml

<?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="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/lv_menu"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
 
</LinearLayout>


MenuFragment.java

package com.example.horizontalscrollview_01;
 
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
 
public class MenuFragment extends Fragment{
public interface onMenuItemClickListener{
void onItemClick(int id);
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.menu_fragment, null);
ListView menu = (ListView) view.findViewById(R.id.lv_menu);
menu.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1,MainActivity.mMenuData));
menu.setOnItemClickListener(new OnItemClickListener() {
 
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
if(getActivity() instanceof onMenuItemClickListener){
((onMenuItemClickListener) getActivity()).onItemClick(arg2);
}
}
});
return view;
}
}


这里简单说一个事情 ,在MenuFragment中,我们加入 了一个ListView, 还定义了一个接口,用来和Activity交互 。

再看content区域

content_fragment.xml

<?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="match_parent"
android:orientation="vertical" >
<TextView 
android:gravity="center"
android:id="@+id/content_tv"
android:textSize="30sp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>


ContentFragment.java 

package com.example.horizontalscrollview_01;
 
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
public class ContentFragment extends Fragment {
private String content;
public ContentFragment(String str) {
content = str;
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.content_fragment, null);
TextView tv = (TextView) view.findViewById(R.id.content_tv);
tv.setText(content);
return view;
}
 
}


这个没什么也说的,基本的Fragment用法 

最后就是我们主Activity了
MainActivity.java

package com.example.horizontalscrollview_01;
 
import com.example.horizontalscrollview_01.MenuFragment.onMenuItemClickListener;
 
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.widget.Toast;
 
public class MainActivity extends FragmentActivity implements onMenuItemClickListener{
private FragmentManager fm;
private android.support.v4.app.FragmentTransaction transaction;
public static final String[] mMenuData = {"1","2","3","4","5","6","7",
"8","9","10","11","12","13","14",};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupFragment();
}
 
private void setupFragment() {
// TODO Auto-generated method stub
fm = getSupportFragmentManager();
transaction = fm.beginTransaction();
transaction.replace(R.id.menu, new MenuFragment());
transaction.replace(R.id.content, new ContentFragment("1"));
transaction.commit();
}
 
@Override
public void onItemClick(int id) {
// TODO Auto-generated method stub
setContentFragment(String.valueOf(id + 1));
}
 
private void setContentFragment(String id) {
// TODO Auto-generated method stub
fm = getSupportFragmentManager();
transaction = fm.beginTransaction();
transaction.replace(R.id.content, new ContentFragment(id));
transaction.commit();
}
 
}


这里都属于Fragment的用法了,不多说了~

公司的网络 ,喜闻乐见,禁网,截几处图说明下吧~
初始进入的界面



滑动到最左边的图



突然发现,滑动有点不智能,我们需要一点一点的滑动才能调整content区域,当然我们也可以加入一些条件 ,例如设置个滑动临界点,这个可以是一段距离,也可以是一个速度的判断 ,我就加个距离临界点吧,这样才觉得不错 。

在SlidingMen.java中加入

public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
if(getScrollX() >= mContent.getWidth() / 2){
this.smoothScrollTo(mContent.getWidth(), 0);
}else{
this.smoothScrollTo(0, 0);
}
return true;
default:
break;
}
return super.onTouchEvent(ev);
}


 

当我们开始左边红色区域的数字 ,右边区域数字就会跟着变化 ,而且界面不会动 。that's all right , what  is a fucking nice day~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  魅族Settings