• 是男人就下100层【第三层】——高仿交通银行手机客户端界面


    前言:

    从《是男人就下100层》系列博文的【第二层】发表完到现在已经整整三个月了,从前面的访问量和评论来看很多朋友还是喜欢实战类的博文的。毕竟我们都叫“攻城狮”,所以要看是否这个“攻城狮”合格,最终还是要看能不能“建造房子“而不是会画房子,下面我们就从盖鸡窝开始吧!(插播一句广告)很多尊敬老师和专家在总结了自己多年的开发经验后为我们年轻的一辈留下了很多知识,使我们踏在他们的肩膀上行走(这句话听起来怪怪的~~),在此向伟大的前辈们致敬!

    一、演示效果

    先看一下实际的效果吧(我相信这种直接贴图的描述方式比文字描述更给力)

    上面的效果如何?还可以吧!这个界面包括很多Android的基础和自定义组件的知识,是从基础向高级开发进阶的好案例。接下来可不是直接贴代码哦,既然是交流我就要和广大的Android学习及爱好者交流(所以考虑到基础的参差不齐,我将一步一步的进行开发和解释)

    二、轻轻的进入主界面

    1、建立工程及包

    2、闪屏界面
    新建一个SplashActivity并加载activity_splash.xml界面
    SplashActivity.java
    package com.example.jaohangui.activity;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    
    import com.example.jaohangui.R;
    
    public class SplashActivity extends Activity{
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_splash);
    		
    		new Handler().postDelayed(new Runnable() {
    			
    			@Override
    			public void run() {
    				Intent intent = new 
    						Intent(SplashActivity.this, MainActivity.class);
    				startActivity(intent);
    				finish();
    			}
    		}, 1000);
    	}
    }
    
    activity_splash.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" 
        android:background="@drawable/splashscreenimage">
    </LinearLayout>
    
    3、实现绚丽的左右滑动
    首先自定义一个可以左右滑动的ViewGroup,关于该部分详细请看我的另外一篇博文:http://blog.csdn.net/dawanganban/article/details/24303563
    在开始下面的工作之前,我们先来看一下Android系统中坐标的概念:
    首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对 Canvas对象进行了一定的操作,例如 : translate(平移)、clipRect(剪切)等,以便达到我们的对该Canvas对象绘制的要求 ,我们可以将这种无边界的视图称为“视图坐标”-----它不受物理屏幕限制。通常我们所理解的一个Layout布局文件只是该视图的显示区域,超过了这个显示区域将不能显示到父视图的区域中 ,对应的,我们可以将这种有边界的视图称为“布局坐标”------ 父视图给子视图分配的布局(layout)大小。而且, 一个视图的在屏幕的起始坐标位于视图坐标起始处,如下图所示。
    由于布局坐标只能显示特定的一块内容,所以我们只有移动布局坐标的坐标原点就可以将视图坐标的任何位置显示出来。
    实现原理:在LinearLayout中添加三个View并在onLayout中设置三个View的布局,通过Scroller类来实现三个View的移动。
    package com.example.jaohangui.view;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.Scroller;
    
    public class MyScrollLeftRightView extends LinearLayout{
    
    	private Scroller mScroller;
    	
    	private View mLeftView;  //坐标界面
    	private View mMainView;  //中间主界面
    	private View mRightView; //右边界面
    	
    	private float mMeasureWight = 3.0f / 5; //菜单界面比例
    	private int mWidth;	
    	private int mHeight;
    	
    	private boolean isLocked = false;
    	private boolean isToLeft = false;
    	private static int CENTER_PAGE = 1;
    	private static int LEFT_PAGE = 0;
    	private static int RIGHT_PAGE = 2;
    	private int currentPage = CENTER_PAGE;
    	
    	public MyScrollLeftRightView(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		mScroller = new Scroller(context);
    	}
    	
    	@Override
    	protected void onLayout(boolean changed, int l, int t, int r, int b) {
    		super.onLayout(changed, l, t, r, b);
    		mLeftView.layout(-(int)(mWidth * mMeasureWight), 0, 0, mHeight);
    		mMainView.layout(0, 0, mWidth, mHeight);
    		mRightView.layout(mWidth, 0, mWidth + (int)(mWidth * mMeasureWight), mHeight);
    	}
    	
    	@Override
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    		mWidth = MeasureSpec.getSize(widthMeasureSpec);
    		mHeight = MeasureSpec.getSize(heightMeasureSpec);
    	}
    	
    	/**
    	 * 添加左边界面内容
    	 * @param view
    	 */
    	public void setLeftView(View view){
    		mLeftView = view;
    		addView(mLeftView);
    	}
    	
    	/**
    	 * 添加主界面内容
    	 * @param view
    	 */
    	public void setMainView(View view){
    		mMainView = view;
    		addView(mMainView);
    	}
    	
    	/**
    	 * 添加右边界面内容
    	 * @param view
    	 */
    	public void setRightView(View view){
    		mRightView = view;
    		addView(mRightView);
    	}
    	
    	private float mDownX;
    	@Override
    	public boolean onTouchEvent(MotionEvent event) {
    		float x = event.getX();
    		switch (event.getAction()) {
    		case MotionEvent.ACTION_DOWN:
    			mDownX = x;
    			break;
    		case MotionEvent.ACTION_UP:
    			int dis = (int)(x - mDownX); //滑动的距离
    			if(Math.abs(dis) > (mWidth * mMeasureWight / 3)){
    				if(dis > 0){
    					toRightMove();
    				}else{
    					toLeftMove();
    				}
    			}
    			break;
    
    		default:
    			break;
    		}
    		return true;
    	}
    	
    	@Override
    	public void computeScroll() {
    		super.computeScroll();
    		if(mScroller.computeScrollOffset()){
    			isLocked = true;
    			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    			postInvalidate();
    		}else{
    			if(currentPage == CENTER_PAGE){
    				if(isToLeft){
    					currentPage = RIGHT_PAGE;
    				}else{
    					currentPage = LEFT_PAGE;
    				}
    			}else{
    				currentPage = CENTER_PAGE;
    			}
    			isLocked = false;
    		}
    	}
    	
    	public void toRightMove(){
    		if(currentPage == LEFT_PAGE || isLocked){
    			return;
    		}
    		int dx = (int)(mWidth * mMeasureWight);
    		mScroller.startScroll(getScrollX(), 0, -dx, 0, 500);
    		invalidate();
    		isToLeft = false;
    	}
    	
    	public void toLeftMove(){
    		if(currentPage == RIGHT_PAGE || isLocked){
    			return;
    		}
    		System.out.println("ok");
    		int dx = (int)(mWidth * mMeasureWight);
    		mScroller.startScroll(getScrollX(), 0, dx, 0, 500);
    		invalidate();
    		isToLeft = true;
    	}
    }
    然后在主Activity中添加左、中、右三个界面布局文件
    package com.example.jaohangui.activity;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    
    import com.example.jaohangui.R;
    import com.example.jaohangui.view.MyScrollLeftRightView;
    
    public class MainActivity extends Activity {
    	private MyScrollLeftRightView mScrollView;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		mScrollView = (MyScrollLeftRightView)findViewById(R.id.left_right_scrollview);
    		final View leftView = getLayoutInflater().inflate(R.layout.activity_main_leftview, null);
    		final View centerView = getLayoutInflater().inflate(R.layout.activity_main_centerview, null);
    		final View rightView = getLayoutInflater().inflate(R.layout.activity_main_rightview, null);
    		mScrollView.setLeftView(leftView);
    		mScrollView.setMainView(centerView);
    		mScrollView.setRightView(rightView);
    	}
    }
    
    交通银行的界面上左右两个界面的切换方式不是通过手势滑动,而是通过点击两个按钮(这个很好实现,将上面的onTouchEvent注释掉)在点击按钮的时候直接调用toRightMove()方法或toLeftMove()方法即可。界面的样子大致浮出水面了...为了方便大家一步步学习,我将这一部分源代码贴出:
    上面工程源代码下载:http://download.csdn.net/detail/lxq_xsyu/7485441

    三、主界面整体布局

    我们添加主界面中的内容如下:

    <?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">
    	<LinearLayout 
    	    android:layout_width="match_parent"
    	    android:layout_height="48dip"
    	    android:orientation="horizontal"
    	    android:background="@drawable/fjp_tb_8">
    	    <Button 
    	        android:id="@+id/leftButton"
    	        android:layout_width="40dip"
    	        android:layout_height="38dip"
    	        android:background="@drawable/title_set_up"
    	        android:layout_marginLeft="10dip"
    	        android:layout_gravity="center_vertical"
    	        />
    	    <TextView
    	        android:layout_width="0dip"
    	        android:layout_height="match_parent"
    	        android:layout_weight="1"
    	        android:layout_gravity="center"
    	        android:gravity="center"
    	        android:text="城市"
    	        android:textSize="22sp"
    	        android:textStyle="bold"/>
    	    <Button 
    	        android:id="@+id/rightButton"
    	        android:layout_width="40dip"
    	        android:layout_height="38dip"
    	        android:layout_marginRight="10dip"
    	        android:background="@drawable/title_right"
    	        android:layout_gravity="center_vertical"/>
    	</LinearLayout>
    	<ImageView 
    	    android:layout_width="match_parent"
    	    android:layout_height="120dip"
    	    android:background="@drawable/xinshijiebaihuo"/>
     	<LinearLayout
            android:id="@+id/tab_ll1"
            android:layout_width="fill_parent"
            android:layout_height="48.0dip"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/text1"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="我的首页"
                android:background="@drawable/menu_tab_center_over"
    			style="@style/main_tab_tv_style"/>
    	    <TextView
                android:id="@+id/text2"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="生活服务"
                android:background="@drawable/menu_tab_left"
    			style="@style/main_tab_tv_style"/>
    	    <TextView
                android:id="@+id/text3"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="金融服务"
                android:background="@drawable/menu_tab_left"
    			style="@style/main_tab_tv_style"/>
    	   <TextView
                android:id="@+id/text4"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="投资理财"
                android:background="@drawable/menu_tab_left"
    			style="@style/main_tab_tv_style"/>
    	</LinearLayout>
    	<android.support.v4.view.ViewPager
    	        android:id="@+id/vPager"
    	        android:layout_width="wrap_content"
    	        android:layout_height="wrap_content"
    	        android:flipInterval="30"
    	        android:background="#EEEDED"
    	        android:persistentDrawingCache="animation"/>		
    </LinearLayout>
    
    在上面的布局文件中可以看到ViewPager组件,ViewPager是Android3.0以上提供的新组建,它能够实现类似微信5.0中的菜单联动滑动效果以及导航引导界面等。

    为了支持Android3.0以下版本的手机,Google为我们提供了一个支持包:android.support.v4.view,当然这个支持包不仅仅包括ViewPager,包中的接口和类如下:
    ViewPager的适配器是PagerAdapter,要实现PagerAdapter要实现以下方法:

    (1)instantiateItem(ViewGroup, int) //添加

    (2)destroyItem(ViewGroup, int, Object)     //删除

    (3)getCount()

    (4)isViewFromObject(View, Object)

    package com.example.jaohangui.activity;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.app.Activity;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.example.jaohangui.R;
    import com.example.jaohangui.view.MyScrollLeftRightView;
    
    public class MainActivity extends Activity {
    	private MyScrollLeftRightView mScrollView;
    	private ViewPager viewPager;//页卡内容
    	private List<View> views;// Tab页面列表
    	private View centerView;
    	
    	private TextView mTextTitle1;
    	private TextView mTextTitle2;
    	private TextView mTextTitle3;
    	private TextView mTextTitle4;
    	
    	private View view1;
    	private View view2;
    	private View view3;
    	private View view4;
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		mScrollView = (MyScrollLeftRightView)findViewById(R.id.left_right_scrollview);
    		final View leftView = getLayoutInflater().inflate(R.layout.activity_main_leftview, null);
    		centerView = getLayoutInflater().inflate(R.layout.activity_main_centerview, null);
    		final View rightView = getLayoutInflater().inflate(R.layout.activity_main_rightview, null);
    		mScrollView.setLeftView(leftView);
    		mScrollView.setMainView(centerView);
    		InitCenterView();
    		mScrollView.setRightView(rightView);
    		
    	}
    	
    	private void InitCenterView() {
    		viewPager=(ViewPager) centerView.findViewById(R.id.vPager);
    		mTextTitle1 = (TextView) centerView.findViewById(R.id.text1);
    		mTextTitle2 = (TextView) centerView.findViewById(R.id.text2);
    		mTextTitle3 = (TextView) centerView.findViewById(R.id.text3);
    		mTextTitle4 = (TextView) centerView.findViewById(R.id.text4);
    		mTextTitle1.setOnClickListener(new MyOnClickListener(0));
    		mTextTitle2.setOnClickListener(new MyOnClickListener(1));
    		mTextTitle3.setOnClickListener(new MyOnClickListener(2));
    		mTextTitle4.setOnClickListener(new MyOnClickListener(3));
    		Button leftButton = (Button) centerView.findViewById(R.id.leftButton);
    		Button rightButton = (Button) centerView.findViewById(R.id.rightButton);
    		leftButton.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View arg0) {
    				
    				if(mScrollView.currentPage == MyScrollLeftRightView.CENTER_PAGE){
    					mScrollView.toRightMove();
    				}else{
    					mScrollView.toLeftMove();
    				}
    			}
    		});
    		rightButton.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View arg0) {
    				if(mScrollView.currentPage == MyScrollLeftRightView.CENTER_PAGE){
    					mScrollView.toLeftMove();
    				}else{
    					mScrollView.toRightMove();
    				}
    			}
    		});
    		views=new ArrayList<View>();
    		LayoutInflater inflater=getLayoutInflater();
    		view1 = inflater.inflate(R.layout.main_tab_layout_0, null);
    		view2 = inflater.inflate(R.layout.main_tab_layout_1, null);
    		view3 = inflater.inflate(R.layout.main_tab_layout_2, null);
    		view4 = inflater.inflate(R.layout.main_tab_layout_3, null);
    
    		views.add(view1);
    		views.add(view2);
    		views.add(view3);
    		views.add(view4);
    		
    		viewPager.setAdapter(new MyViewPagerAdapter(views));
    		viewPager.setCurrentItem(0);
    		viewPager.setOnPageChangeListener(new MyOnPageChangeListener());
    	}
    	
    	public class MyViewPagerAdapter extends PagerAdapter{
    		private List<View> mListViews;
    		
    		public MyViewPagerAdapter(List<View> mListViews) {
    			this.mListViews = mListViews;
    		}
    
    		@Override
    		public void destroyItem(ViewGroup container, int position, Object object) 	{	
    			container.removeView(mListViews.get(position));
    		}
    
    
    		@Override
    		public Object instantiateItem(ViewGroup container, int position) {			
    			 container.addView(mListViews.get(position), 0);
    			 return mListViews.get(position);
    		}
    
    		@Override
    		public int getCount() {			
    			return  mListViews.size();
    		}
    		
    		@Override
    		public boolean isViewFromObject(View arg0, Object arg1) {			
    			return arg0==arg1;
    		}
    	}
    	
    	 private class MyOnClickListener implements OnClickListener{  
    	        private int index=0;  
    	        public MyOnClickListener(int i){  
    	            index=i;  
    	        }  
    	        public void onClick(View v) {  
    	        	System.out.println("clike = " + index);
    	            viewPager.setCurrentItem(index);              
    	        }  
    	}  
    	
       public class MyOnPageChangeListener implements OnPageChangeListener{
    		public void onPageScrollStateChanged(int arg0) {
    
    		}
    		public void onPageScrolled(int arg0, float arg1, int arg2) {
    
    		}
    		public void onPageSelected(int arg0){
    			System.out.println("changeTabState = " + arg0);
    			changeTabState(arg0);
    		}
        }
    		
    	private void changeTabState(int index){
    		switch (index) {
    		case 0:
    			mTextTitle1.setTextColor(Color.rgb(27, 158, 233));
    			mTextTitle2.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle3.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle4.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle1.setBackgroundResource(R.drawable.menu_tab_center_over);
    			mTextTitle2.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle3.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle4.setBackgroundResource(R.drawable.menu_tab_left);
    			break;
    		case 1:
    			mTextTitle1.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle2.setTextColor(Color.rgb(27, 158, 233));
    			mTextTitle3.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle4.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle1.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle2.setBackgroundResource(R.drawable.menu_tab_center_over);
    			mTextTitle3.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle4.setBackgroundResource(R.drawable.menu_tab_left);
    			break;
    		case 2:
    			mTextTitle1.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle2.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle3.setTextColor(Color.rgb(27, 158, 233));
    			mTextTitle4.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle1.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle2.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle3.setBackgroundResource(R.drawable.menu_tab_center_over);
    			mTextTitle4.setBackgroundResource(R.drawable.menu_tab_left);
    			break;
    		case 3:
    			mTextTitle1.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle2.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle3.setTextColor(Color.rgb(0, 0, 0));
    			mTextTitle4.setTextColor(Color.rgb(27, 158, 233));
    			mTextTitle1.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle2.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle3.setBackgroundResource(R.drawable.menu_tab_left);
    			mTextTitle4.setBackgroundResource(R.drawable.menu_tab_center_over);
    			break;
    
    		default:
    			break;
    		}
    	} 
    	   
    }
    实现效果如下:
    如果ViewPager要实现和微信上部一样的滑动联动效果,可以参考我的另外一篇博文:http://blog.csdn.net/dawanganban/article/details/25773891

    当然我们的目的肯定不是盖鸡窝,去建造一个坚固(健壮)的“猪圈”才对得起我们“攻城狮”这个称呼吧,至于如何才能建成,期待下一篇吧....,建造一个东西所用的基本材料大致相同,但是具体的建造过程却千差万别,所以以上只是将个人的建造方式拿出来献献丑,期待前辈和同行的指导,我们努力早日共同建造好我们期待的“猪圈”吧,呵呵。


    另外“阳光小强”本篇博文很荣幸的参加了博客大赛,如果您觉得对您有帮助,请支持小强吧,
    投票地址:http://vote.blog.csdn.net/Article/Details?articleid=30101091
  • 相关阅读:
    23.什么是控制文件?
    路由器原理及路由协议
    大家帮忙看看,不会即使显示串口缓冲数据
    c# interface
    ip classless&no ip classless
    Visual Studio 2010 Visual C++ 确定要重新分发的 DLL
    fibonacci算法
    loopback端口作用
    疑惑的virtual method
    Read MBR via ReadFile function
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468903.html
Copyright © 2020-2023  润新知