热门手机应用界面分析--微信欢迎页面

来源:互联网 发布:01年总决赛艾弗森数据 编辑:程序博客网 时间:2024/04/29 17:45

我们知道,微信等手机应用在第一次启动时有欢迎界面,用于介绍程序的特性及使用方式:



那么我们可以针对这个界面分析:

我们启动monitor.bat,我们观察页面布局:

在TreeView窗口中我们看到有好几个Layout布局嵌套,直到我们看到一个Gallery,OK,我们大致知道了实现思路。

下面我们针对上面的一个页面进行分析。

我们看到页面上的内容是分成共几块个区域:

  • 一个RelativeLayout负责显示当前区域;另一个RelativeLayout负责显示移入效果;
  • 一个ImageView负责显示那几个小人;
  • 一个TextView负责显示那段文字;
  • 使用3个ImageView来负责显示当前处于哪个页面;


下面我们需要去找对应的Layout:

我们解压缩安装包,基本可以肯定布局文件应该是whats_news.xml,可惜混淆掉了~~~,没关系,我们可以Do It Youself, Let's go!



核心代码:

应用首次启动的判断(在主窗口中):

        boolean firstLogin = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FLAG_FIRST_LOGIN, true);        if (firstLogin) {            startActivity(new Intent("com.freesoft.whatsnew.activity.WelcomeActivity"));        }

在应用程序中配置这个welcome activity的过滤器:

        <activity            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"            android:name="com.freesoft.whatsnew.activity.WelcomeActivity"            android:label="guider" >            <intent-filter>                <action android:name="com.freesoft.whatsnew.activity.WelcomeActivity" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>

这个WelcomeActivity的代码:

布局文件:

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/main_layout"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="@drawable/background_holo_dark" >    <com.freesoft.whatsnew.component.WelcomeGallery        android:id="@+id/what_news_gallery"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:clickable="true"        android:focusable="true"        android:spacing="0.0dip"        android:unselectedAlpha="1.2" />    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_gravity="center"        android:background="@null" >        <com.freesoft.whatsnew.component.PageControlView            android:id="@+id/what_news_page_control"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:layout_marginBottom="17.5dip"            android:background="@null"            android:gravity="bottom|center" />    </LinearLayout>    <RelativeLayout        xmlns:android="http://schemas.android.com/apk/res/android"        android:id="@+id/mm_door"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="@drawable/background_holo_dark"        android:orientation="horizontal"        android:visibility="gone" >        <ImageView            android:id="@+id/mm_left"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:adjustViewBounds="true"            android:scaleType="fitEnd"            android:src="@drawable/whatsnew_08_01" />        <ImageView            android:id="@+id/mm_right"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:adjustViewBounds="true"            android:scaleType="fitEnd"            android:src="@drawable/whatsnew_08_02" />    </RelativeLayout></FrameLayout>

Java代码:

package com.freesoft.whatsnew.activity;import com.freesoft.whatsnew.R;import com.freesoft.whatsnew.component.GalleryAdapter;import com.freesoft.whatsnew.component.PageControlView;import com.freesoft.whatsnew.component.WelcomeGallery;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemSelectedListener;import android.widget.ImageView;public class WelcomeActivity extends Activity implements OnItemSelectedListener {    private View viewDoor = null;    public ImageView imageLeft = null;    public ImageView imageRight = null;    private WelcomeGallery gallery = null;    private GalleryAdapter adapter = null;    private PageControlView indicateView = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.whats_news);        initCompnents();    }private void initCompnents() {gallery = (WelcomeGallery) findViewById(R.id.what_news_gallery);        adapter = new GalleryAdapter(this);        gallery.setFadingEdgeLength(0);        gallery.setSpacing(-1);        gallery.setAdapter(adapter);        gallery.setOnItemSelectedListener(this);        indicateView = (PageControlView) findViewById(R.id.what_news_page_control);        indicateView.setIndication(gallery.getCount(), 0);        viewDoor = findViewById(R.id.mm_door);        imageLeft = (ImageView) findViewById(R.id.mm_left);        imageRight = (ImageView) findViewById(R.id.mm_right);}public void openDoor() {viewDoor.setVisibility(View.VISIBLE);        imageLeft.startAnimation(adapter.setAnimation(R.anim.slide_left));        imageRight.startAnimation(adapter.setAnimation(R.anim.slide_right));}public void gotoHome() {    imageLeft.setVisibility(View.GONE);    imageRight.setVisibility(View.GONE);        finish();}    @Override    public void onItemSelected(AdapterView<?> parent, View view, int position,            long id) {        if (indicateView != null) {            indicateView.setIndication(parent.getCount(), position);        }    }    @Override    public void onNothingSelected(AdapterView<?> parent) {    }}

Gallery代码:

package com.freesoft.whatsnew.component;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.MotionEvent;import android.widget.Gallery;public class WelcomeGallery extends Gallery {    public WelcomeGallery(Context context) {        super(context);        setStaticTransformationsEnabled(true);    }    public WelcomeGallery(Context context, AttributeSet attrs) {        super(context, attrs);        setStaticTransformationsEnabled(true);    }    public WelcomeGallery(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        setStaticTransformationsEnabled(true);    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,            float velocityY) {        if (velocityX > 0) {            onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, null);        } else {            onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);        }        return true;    }}



Adapter:

package com.freesoft.whatsnew.component;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.preference.PreferenceManager;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.AnimationUtils;import android.widget.BaseAdapter;import android.widget.Button;import com.freesoft.whatsnew.R;import com.freesoft.whatsnew.activity.WelcomeActivity;public class GalleryAdapter extends BaseAdapter implements OnClickListener, AnimationListener{private Context context;    private LayoutInflater inflater = null;    // Layout of the Gallery    private int[] layouts = new int[] {            R.layout.whats_news_gallery_fornew_one,            R.layout.whats_news_gallery_fornew_two,            R.layout.whats_news_gallery_fornew_three,            R.layout.whats_news_gallery_fornew_four };    public GalleryAdapter(Context ctx) {        context = ctx;        inflater = (LayoutInflater) context                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);    }    @Override    public int getCount() {        return layouts.length;    }    @Override    public Object getItem(int position) {        return Integer.valueOf(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if (convertView == null) {        // dynamic loading            convertView = inflater.inflate(layouts[position], null);            if (position == (layouts.length - 1)) {            // if the last page, find the button & set button on click                Button btn = (Button) convertView                        .findViewById(R.id.whats_new_start_btn);                btn.setOnClickListener(this);            }        }        return convertView;    }    @Override    public void onClick(View v) {    // 最后一个页面,button开始动画    ((WelcomeActivity)context).openDoor();    }public Animation setAnimation(int resId) {        Animation anim = AnimationUtils.loadAnimation(context, resId);        anim.setAnimationListener(this);        return anim;    }    @Override    public void onAnimationStart(Animation animation) {    }    @Override    public void onAnimationEnd(Animation animation) {        SharedPreferences sp = PreferenceManager                .getDefaultSharedPreferences(context);        Editor edit = sp.edit();        String str = context.getString(R.string.FLAG_FIRST_LOGIN);        edit.putBoolean(str, false);        edit.commit();                ((WelcomeActivity)context).gotoHome();    }    @Override    public void onAnimationRepeat(Animation animation) {    }}


PageControl代码:

package com.freesoft.whatsnew.component;import com.freesoft.whatsnew.R;import android.content.Context;import android.util.AttributeSet;import android.widget.ImageView;import android.widget.LinearLayout;public class PageControlView extends LinearLayout {private Context mContext;public PageControlView(Context ctx) {super(ctx);mContext = ctx;}public PageControlView(Context ctx, AttributeSet attrs) {super(ctx, attrs);mContext = ctx;}public void setIndication(int cnt, int index) {if (index < 0 || index > cnt)index = 0;removeAllViews();for (int i = 0; i < cnt; i++) {ImageView iv = new ImageView(mContext);iv.setImageResource(index == i ? R.drawable.page_indicator_focused: R.drawable.page_indicator_unfocused);if (i != 0 || i != cnt - 1) {iv.setPadding(8, 0, 8, 0);}addView(iv);}}}


本文参考了Android给自己的app编写用户指南这篇文章,仅仅加上了自己的一些理解和经验,也感谢原作者。


另外我简化了一下原作者的代码,省略了一些动画等锦上添花的东西,比较原始的演示了一下如何实现使用向导,下载地址:实现Splash的简化版本