微信高仿

原文链接:http://www.cnblogs.com/liuzhenlong/p/4177308.html

在上一篇博客中,我大概的复制了一下这份源代,可能没有怎么说清楚,在这一篇代码中,我来仔细的帮大家把微信的高仿界面说明白:

(本人用的编译环境是Android Studio1.0版本的,用的是Android4.4.4的SDK)

这就是我已经写好的微信高仿界面,好了,说了那么都多,开始写我们的代码吧:

首先,我们要新建一个项目随便叫做WeChatSimple,我们需要在menu文件里面的xml文件编译一下,具体代码如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.wechatsample.MainActivity" >

    <item
        android:id="@+id/action_search"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@drawable/actionbar_search_icon"
        android:showAsAction="ifRoom|collapseActionView"
        android:title="@string/action_search"/>
    <item
        android:id="@+id/action_plus"
        android:actionProviderClass="com.example.wechatsample.PlusActionProvider"
        android:icon="@drawable/actionbar_add_icon"
        android:showAsAction="ifRoom"
        android:title="@string/action_plus"/>
    <item
        android:id="@+id/action_album"
        android:icon="@drawable/ofm_photo_icon"
        android:title="@string/action_album"/>
    <item
        android:id="@+id/action_collection"
        android:icon="@drawable/ofm_collect_icon"
        android:title="@string/action_collection"/>
    <item
        android:id="@+id/action_card"
        android:icon="@drawable/ofm_card_icon"
        android:title="@string/action_card"/>
    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/ofm_setting_icon"
        android:title="@string/action_settings"/>
    <item
        android:id="@+id/action_feed"
        android:icon="@drawable/ofm_feedback_icon"
        android:title="@string/action_feed"/>

</menu>

当然,我们需要修改一下String文件里的代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">微信</string>
    <string name="action_search">搜索</string>
    <string name="action_plus">功能</string>
    <string name="action_album">我的相册</string>
    <string name="action_collection">我的收藏</string>
    <string name="action_card">我的银行卡</string>
    <string name="action_settings">设置</string>
    <string name="action_feed">意见反馈</string>
    <string name="plus_group_chat">发起群聊</string>
    <string name="plus_add_friend">添加朋友</string>
    <string name="plus_video_chat">视频聊天</string>
    <string name="plus_scan">扫一扫</string>
    <string name="plus_take_photo">拍照分享</string>
</resources>

 

其中里面的图片都是我已经之前准备好了大家可以在我的这篇博客的最后下载我的源文件进行查看;好了,我们已经写完了menu文件里的xml文了,接下来会发现里面有一个自定义的Action Provider,叫作PlusActionProvider。这个主要是用于模拟微信中那个加号的子菜单的,下面我们就来实现这个类,代码如下:

package com.example.wechatsample;

import android.content.Context;
import android.view.ActionProvider;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.SubMenu;
import android.view.View;
/**
 * author :liu Zhenlong
 *
 * time:2014/12/21
 * */

public class PlusActionProvider extends ActionProvider {

    private Context context;

    public PlusActionProvider(Context context) {
        super(context);
        this.context = context;
    }

    @Override
    public View onCreateActionView() {
        return null;
    }

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        subMenu.clear();
        subMenu.add(context.getString(R.string.plus_group_chat))
                .setIcon(R.drawable.ofm_group_chat_icon)
                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return true;
                    }
                });
        subMenu.add(context.getString(R.string.plus_add_friend))
                .setIcon(R.drawable.ofm_add_icon)
                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return false;
                    }
                });
        subMenu.add(context.getString(R.string.plus_video_chat))
                .setIcon(R.drawable.ofm_video_icon)
                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return false;
                    }
                });
        subMenu.add(context.getString(R.string.plus_scan))
                .setIcon(R.drawable.ofm_qrcode_icon)
                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return false;
                    }
                });
        subMenu.add(context.getString(R.string.plus_take_photo))
                .setIcon(R.drawable.ofm_camera_icon)
                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return false;
                    }
                });
    }

    @Override
    public boolean hasSubMenu() {
        return true;
    }

}

这样,我们的加号所形成的下拉列表就基本OK,(虽然我在这里面定义了点击事件,但是并没有什么具体的用处,我们只是在写微信的界面而已,不需要实现具体的功能)

好了,上面的代码学过Android的人都会觉得十分好理解,现在我们就看是写MainActivity里面的代码了:

package com.example.wechatsample;

/**
 *  author : LiuZhenlong
 * 
 * time: 2014/12/21
 * **/

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Menu;
import android.view.ViewConfiguration;
import android.view.Window;
import com.example.wechatsample.astuetz.PagerSlidingTabStrip;


public class MainActivity extends FragmentActivity {

    /**
     * 聊天界面的Fragment
     */
    private ChatFragment chatFragment;

    /**
     * 发现界面的Fragment
     */
    private FoundFragment foundFragment;

    /**
     * 通讯录界面的Fragment
     */
    private ContactsFragment contactsFragment;

    /**
     * PagerSlidingTabStrip的实例
     */
    private PagerSlidingTabStrip tabs;

    /**
     * 获取当前屏幕的密度
     */
    private DisplayMetrics dm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setOverflowShowingAlways();
        dm = getResources().getDisplayMetrics();
        ViewPager pager = (ViewPager) findViewById(R.id.pager);
        tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
        tabs.setViewPager(pager);
        setTabsValue();
    }

    /**
     * 对PagerSlidingTabStrip的各项属性进行赋值。
     */
    private void setTabsValue() {
        // 设置Tab是自动填充满屏幕的
        tabs.setShouldExpand(true);
        // 设置Tab的分割线是透明的
        tabs.setDividerColor(Color.TRANSPARENT);
        // 设置Tab底部线的高度
        tabs.setUnderlineHeight((int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 1, dm));
        // 设置Tab Indicator的高度
        tabs.setIndicatorHeight((int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, 4, dm));
        // 设置Tab标题文字的大小
        tabs.setTextSize((int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP, 16, dm));
        // 设置Tab Indicator的颜色
        tabs.setIndicatorColor(Color.parseColor("#45c01a"));
        // 设置选中Tab文字的颜色 (这是我自定义的一个方法)
        tabs.setSelectedTextColor(Color.parseColor("#45c01a"));
        // 取消点击Tab时的背景色
        tabs.setTabBackground(0);
    }

    public class MyPagerAdapter extends FragmentPagerAdapter {

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        private final String[] titles = {"聊天", "发现", "通讯录"};

        @Override
        public CharSequence getPageTitle(int position) {
            return titles[position];
        }

        @Override
        public int getCount() {
            return titles.length;
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    if (chatFragment == null) {
                        chatFragment = new ChatFragment();
                    }
                    return chatFragment;
                case 1:
                    if (foundFragment == null) {
                        foundFragment = new FoundFragment();
                    }
                    return foundFragment;
                case 2:
                    if (contactsFragment == null) {
                        contactsFragment = new ContactsFragment();
                    }
                    return contactsFragment;
                default:
                    return null;
            }
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
            if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
                try {
                    Method m = menu.getClass().getDeclaredMethod(
                            "setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (Exception e) {
                }
            }
        }
        return super.onMenuOpened(featureId, menu);
    }

    private void setOverflowShowingAlways() {
        try {
            ViewConfiguration config = ViewConfiguration.get(this);
            Field menuKeyField = ViewConfiguration.class
                    .getDeclaredField("sHasPermanentMenuKey");
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 到了现在,我们已经把ActionBar给写好了,但是你运行看看发现还是会有很大的差异,因为我们的字体大小什么的都还没有定义,所以自然不怎么像,所以,自然而然我们也可以去Vaule里面的Style。xml文件里面去看看编译一下,具体的代码如下:

Styles:

<resources>

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

</resources>

 

attrs.xml文件里的代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="PagerSlidingTabStrip">
        <attr name="pstsIndicatorColor" format="color" />
        <attr name="pstsUnderlineColor" format="color" />
        <attr name="pstsDividerColor" format="color" />
        <attr name="pstsIndicatorHeight" format="dimension" />
        <attr name="pstsUnderlineHeight" format="dimension" />
        <attr name="pstsDividerPadding" format="dimension" />
        <attr name="pstsTabPaddingLeftRight" format="dimension" />
        <attr name="pstsScrollOffset" format="dimension" />
        <attr name="pstsTabBackground" format="reference" />
        <attr name="pstsShouldExpand" format="boolean" />
        <attr name="pstsTextAllCaps" format="boolean" />
    </declare-styleable>

</resources>

 

color.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="background_tab_pressed">#6633B5E5</color>
</resources>

 

在这里面,我们将颜色什么的都已经定义好了,接下来,我们就需要修改一下AndroidMainfest.java里面的代码,对文件进行一个注册,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wechatsample" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:logo="@drawable/logo">

        <activity
            android:name="com.example.wechatsample.MainActivity"
            android:label="@string/app_name"
            android:logo="@drawable/logo">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

写到这里的时候读者们可以去试着跑一下你们的代码,你们会发下你们写的微信头部几乎就可以以假乱真了,如果你们完成了,说明大家的ActionBar学的还是很不错的,但是,我们的任务还没有结束哦,

我们的三个界面还没有做出来呢,至少我们不能让三个界面都是一样的吧,下面的聊天、发现、通讯录这三个Tab我们还没做呢。如此高端大气上档次的功能是不能就这么放过的,因此下面我们就来探究一下如何才能实现微信那样的Tab效果,所以我们的任务还有很大:

首先,我们要写出三个界面对吧,大家首先想到的方法是什么?没错,就是我们一个很重要的一节Fragment对吧

好的,废话不多说了,让我们就继续:

  这里我们介绍一个java程序PagerSlidingTabStrip,PagerSlidingTabStrip是GitHub上的一个开源框架,由Andreas Stuetz编写,它可以完成和ActionBar Tab基本类似的功能,不过由于是完全开源的,我们可以随意修改其中的代码,因而扩展性非常好。由于PagerSlidingTabStrip有将近八百行的代码,大家不要畏惧,代码多我们只需要修改就好,慢慢来:

package com.example.wechatsample.astuetz;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.Locale;

import com.example.wechatsample.R;

public class PagerSlidingTabStrip extends HorizontalScrollView {

    public interface IconTabProvider {
        public int getPageIconResId(int position);
    }

    // @formatter:off
    private static final int[] ATTRS = new int[] {
            android.R.attr.textSize,
            android.R.attr.textColor
    };
    // @formatter:on

    private LinearLayout.LayoutParams defaultTabLayoutParams;
    private LinearLayout.LayoutParams expandedTabLayoutParams;

    private final PageListener pageListener = new PageListener();
    public OnPageChangeListener delegatePageListener;

    private LinearLayout tabsContainer;
    private ViewPager pager;

    private int tabCount;

    private int currentPosition = 0;
    private int selectedPosition = 0;
    private float currentPositionOffset = 0f;

    private Paint rectPaint;
    private Paint dividerPaint;

    private int indicatorColor = 0xFF666666;
    private int underlineColor = 0x1A000000;
    private int dividerColor = 0x1A000000;

    private boolean shouldExpand = false;
    private boolean textAllCaps = true;

    private int scrollOffset = 52;
    private int indicatorHeight = 8;
    private int underlineHeight = 2;
    private int dividerPadding = 12;
    private int tabPadding = 24;
    private int dividerWidth = 1;

    private int tabTextSize = 12;
    private int tabTextColor = 0xFF666666;
    private int selectedTabTextColor = 0xFF666666;
    private Typeface tabTypeface = null;
    private int tabTypefaceStyle = Typeface.NORMAL;

    private int lastScrollX = 0;

    private int tabBackgroundResId = R.drawable.background_tab;

    private Locale locale;

    public PagerSlidingTabStrip(Context context) {
        this(context, null);
    }

    public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        setFillViewport(true);
        setWillNotDraw(false);

        tabsContainer = new LinearLayout(context);
        tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
        tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        addView(tabsContainer);

        DisplayMetrics dm = getResources().getDisplayMetrics();

        scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
        indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
        underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
        dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
        tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
        dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
        tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);

        // get system attrs (android:textSize and android:textColor)

        TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);

        tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
        tabTextColor = a.getColor(1, tabTextColor);

        a.recycle();

        // get custom attrs

        a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);

        indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
        underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
        dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
        indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
        underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
        dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
        tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
        tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
        shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
        scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
        textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);

        a.recycle();

        rectPaint = new Paint();
        rectPaint.setAntiAlias(true);
        rectPaint.setStyle(Style.FILL);

        dividerPaint = new Paint();
        dividerPaint.setAntiAlias(true);
        dividerPaint.setStrokeWidth(dividerWidth);

        defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);

        if (locale == null) {
            locale = getResources().getConfiguration().locale;
        }
    }

    public void setViewPager(ViewPager pager) {
        this.pager = pager;

        if (pager.getAdapter() == null) {
            throw new IllegalStateException("ViewPager does not have adapter instance.");
        }

        pager.setOnPageChangeListener(pageListener);

        notifyDataSetChanged();
    }

    public void setOnPageChangeListener(OnPageChangeListener listener) {
        this.delegatePageListener = listener;
    }

    public void notifyDataSetChanged() {

        tabsContainer.removeAllViews();

        tabCount = pager.getAdapter().getCount();

        for (int i = 0; i < tabCount; i++) {

            if (pager.getAdapter() instanceof IconTabProvider) {
                addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
            } else {
                addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
            }

        }

        updateTabStyles();

        getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                currentPosition = pager.getCurrentItem();
                scrollToChild(currentPosition, 0);
            }
        });

    }

    private void addTextTab(final int position, String title) {

        TextView tab = new TextView(getContext());
        tab.setText(title);
        tab.setGravity(Gravity.CENTER);
        tab.setSingleLine();
        addTab(position, tab);
    }

    private void addIconTab(final int position, int resId) {

        ImageButton tab = new ImageButton(getContext());
        tab.setImageResource(resId);

        addTab(position, tab);

    }

    private void addTab(final int position, View tab) {
        tab.setFocusable(true);
        tab.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                pager.setCurrentItem(position);
            }
        });

        tab.setPadding(tabPadding, 0, tabPadding, 0);
        tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
    }

    private void updateTabStyles() {

        for (int i = 0; i < tabCount; i++) {

            View v = tabsContainer.getChildAt(i);

            v.setBackgroundResource(tabBackgroundResId);

            if (v instanceof TextView) {

                TextView tab = (TextView) v;
                tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
                tab.setTypeface(tabTypeface, tabTypefaceStyle);
                tab.setTextColor(tabTextColor);

                // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
                // pre-ICS-build
                if (textAllCaps) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                        tab.setAllCaps(true);
                    } else {
                        tab.setText(tab.getText().toString().toUpperCase(locale));
                    }
                }
                if (i == selectedPosition) {
                    tab.setTextColor(selectedTabTextColor);
                }
            }
        }

    }

    private void scrollToChild(int position, int offset) {

        if (tabCount == 0) {
            return;
        }

        int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;

        if (position > 0 || offset > 0) {
            newScrollX -= scrollOffset;
        }

        if (newScrollX != lastScrollX) {
            lastScrollX = newScrollX;
            scrollTo(newScrollX, 0);
        }

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (isInEditMode() || tabCount == 0) {
            return;
        }

        final int height = getHeight();

        // draw underline
        rectPaint.setColor(underlineColor);
        canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);

        // draw indicator line
        rectPaint.setColor(indicatorColor);

        // default: line below current tab
        View currentTab = tabsContainer.getChildAt(currentPosition);
        float lineLeft = currentTab.getLeft();
        float lineRight = currentTab.getRight();

        // if there is an offset, start interpolating left and right coordinates between current and next tab
        if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {

            View nextTab = tabsContainer.getChildAt(currentPosition + 1);
            final float nextTabLeft = nextTab.getLeft();
            final float nextTabRight = nextTab.getRight();

            lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
            lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
        }

        canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);

        // draw divider

        dividerPaint.setColor(dividerColor);
        for (int i = 0; i < tabCount - 1; i++) {
            View tab = tabsContainer.getChildAt(i);
            canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
        }
    }

    private class PageListener implements OnPageChangeListener {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            currentPosition = position;
            currentPositionOffset = positionOffset;

            scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));

            invalidate();

            if (delegatePageListener != null) {
                delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                scrollToChild(pager.getCurrentItem(), 0);
            }

            if (delegatePageListener != null) {
                delegatePageListener.onPageScrollStateChanged(state);
            }
        }

        @Override
        public void onPageSelected(int position) {
            selectedPosition = position;
            updateTabStyles();
            if (delegatePageListener != null) {
                delegatePageListener.onPageSelected(position);
            }
        }

    }

    public void setIndicatorColor(int indicatorColor) {
        this.indicatorColor = indicatorColor;
        invalidate();
    }

    public void setIndicatorColorResource(int resId) {
        this.indicatorColor = getResources().getColor(resId);
        invalidate();
    }

    public int getIndicatorColor() {
        return this.indicatorColor;
    }

    public void setIndicatorHeight(int indicatorLineHeightPx) {
        this.indicatorHeight = indicatorLineHeightPx;
        invalidate();
    }

    public int getIndicatorHeight() {
        return indicatorHeight;
    }

    public void setUnderlineColor(int underlineColor) {
        this.underlineColor = underlineColor;
        invalidate();
    }

    public void setUnderlineColorResource(int resId) {
        this.underlineColor = getResources().getColor(resId);
        invalidate();
    }

    public int getUnderlineColor() {
        return underlineColor;
    }

    public void setDividerColor(int dividerColor) {
        this.dividerColor = dividerColor;
        invalidate();
    }

    public void setDividerColorResource(int resId) {
        this.dividerColor = getResources().getColor(resId);
        invalidate();
    }

    public int getDividerColor() {
        return dividerColor;
    }

    public void setUnderlineHeight(int underlineHeightPx) {
        this.underlineHeight = underlineHeightPx;
        invalidate();
    }

    public int getUnderlineHeight() {
        return underlineHeight;
    }

    public void setDividerPadding(int dividerPaddingPx) {
        this.dividerPadding = dividerPaddingPx;
        invalidate();
    }

    public int getDividerPadding() {
        return dividerPadding;
    }

    public void setScrollOffset(int scrollOffsetPx) {
        this.scrollOffset = scrollOffsetPx;
        invalidate();
    }

    public int getScrollOffset() {
        return scrollOffset;
    }

    public void setShouldExpand(boolean shouldExpand) {
        this.shouldExpand = shouldExpand;
        notifyDataSetChanged();
    }

    public boolean getShouldExpand() {
        return shouldExpand;
    }

    public boolean isTextAllCaps() {
        return textAllCaps;
    }

    public void setAllCaps(boolean textAllCaps) {
        this.textAllCaps = textAllCaps;
    }

    public void setTextSize(int textSizePx) {
        this.tabTextSize = textSizePx;
        updateTabStyles();
    }

    public int getTextSize() {
        return tabTextSize;
    }

    public void setTextColor(int textColor) {
        this.tabTextColor = textColor;
        updateTabStyles();
    }

    public void setTextColorResource(int resId) {
        this.tabTextColor = getResources().getColor(resId);
        updateTabStyles();
    }

    public int getTextColor() {
        return tabTextColor;
    }

    public void setSelectedTextColor(int textColor) {
        this.selectedTabTextColor = textColor;
        updateTabStyles();
    }

    public void setSelectedTextColorResource(int resId) {
        this.selectedTabTextColor = getResources().getColor(resId);
        updateTabStyles();
    }

    public int getSelectedTextColor() {
        return selectedTabTextColor;
    }

    public void setTypeface(Typeface typeface, int style) {
        this.tabTypeface = typeface;
        this.tabTypefaceStyle = style;
        updateTabStyles();
    }

    public void setTabBackground(int resId) {
        this.tabBackgroundResId = resId;
        updateTabStyles();
    }

    public int getTabBackground() {
        return tabBackgroundResId;
    }

    public void setTabPaddingLeftRight(int paddingPx) {
        this.tabPadding = paddingPx;
        updateTabStyles();
    }

    public int getTabPaddingLeftRight() {
        return tabPadding;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        currentPosition = savedState.currentPosition;
        requestLayout();
    }

    @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState savedState = new SavedState(superState);
        savedState.currentPosition = currentPosition;
        return savedState;
    }

    static class SavedState extends BaseSavedState {
        int currentPosition;

        public SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            currentPosition = in.readInt();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeInt(currentPosition);
        }

        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

}

 

完成了上诉步骤后,修改activity_main.xml.xml(也就是MainActivity对应的布局文件)中的代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.wechatsample.astuetz.PagerSlidingTabStrip
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="40dp" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tabs" />

</RelativeLayout>

 

接着创建ChatFragment、FoundFragment和ContactsFragment,分别对应着聊天、发现、通讯录这三个界面,Fragment中只需放置一个TextView用于表示这个界面即可:

ChatFragment:

package com.example.wechatsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.FrameLayout.LayoutParams;

public class ChatFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        FrameLayout fl = new FrameLayout(getActivity());
        fl.setLayoutParams(params);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, dm);
        TextView v = new TextView(getActivity());
        params.setMargins(margin, margin, margin, margin);
        v.setLayoutParams(params);
        v.setLayoutParams(params);
        v.setGravity(Gravity.CENTER);
        v.setText("聊天界面");
        v.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, dm));
        fl.addView(v);
        return fl;
    }
}

 

FoundFragment:

package com.example.wechatsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.FrameLayout.LayoutParams;


public class FoundFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        FrameLayout fl = new FrameLayout(getActivity());
        fl.setLayoutParams(params);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, dm);
        TextView v = new TextView(getActivity());
        params.setMargins(margin, margin, margin, margin);
        v.setLayoutParams(params);
        v.setLayoutParams(params);
        v.setGravity(Gravity.CENTER);
        v.setText("发现界面");
        v.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, dm));
        fl.addView(v);
        return fl;
    }
}

 

ContactsFragment

package com.example.wechatsample;

/**
 * Created by Liu Zhenlong on 2014/12/16.
 */
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.FrameLayout.LayoutParams;


public class ContactsFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        FrameLayout fl = new FrameLayout(getActivity());
        fl.setLayoutParams(params);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, dm);
        TextView v = new TextView(getActivity());
        params.setMargins(margin, margin, margin, margin);
        v.setLayoutParams(params);
        v.setLayoutParams(params);
        v.setGravity(Gravity.CENTER);
        v.setText("通讯录界面");
        v.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, dm));
        fl.addView(v);
        return fl;
    }
}

 

写到这里,我们的的=微信界面几乎写完了,在这里,我来贴几张图片,大家看看是不是很像呢:

 

好了,我们这次的Android就写到这里了,大家看了有疑问就请留言,尽量解答......


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是安卓开发仿微信界面的代码。 分为3步,第一步是界面的编写,第二步是导航界面,第三步是右上角菜单栏。 开始第一步前先预览一下效果。 第一步,界面。 界面的思路是利用ViewPager+Fragment实现,所以activity_main.xml中添加一个ViewPager。顶部和底部include的顶部栏和底部栏后面再说。 MainActivity的界面activity_main.xml: <?xml version="1.0" encoding="utf-8"?> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 当然,要用到ViewPager+Fragment就要建立Fragment,如图我建了三个Fragment,这个可以根据需要自己创建。 这三个Fragment很类似,这里写出一个,其他以此类推。 package activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.chase.cn.money_of_my.R; /** * Created by Chase on 2017/2/6. */ public class Fragment_tab01 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View tab01 = inflater.inflate(R.layout.fragment_tab01_home,container,false); return tab01; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 此Fragment对应的xml文件: <?xml version="1.0" encoding="utf-8"?> 1 2 3 4 5 6 7 现在回到MainActivity中: package activity; import ... public class MainActivity extends FragmentActivity { private ViewPager mViewPager; private MyFragmentPagerAdapter mAdapter; private List fragmentList; //保存界面的view @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); StatusBarUtil.setWindowStatusBarColor(this, R.color.colorTitleGray); initViews(); initDatas(); } /** * 数据初始化 */ private void initDatas() { //fragment数据源 fragmentList = new ArrayList(); fragmentList.add(new Fragment_tab01()); fragmentList.add(new Fragment_tab02()); fragmentList.add(new Fragment_tab03()); mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentList); mViewPager.setAdapter(mAdapter); } /** * 初始化控件 */ private void initViews() { mViewPager = (ViewPager) findViewById(R.id.vp_mainvp); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 需要编写一个ViewPager的Adapter: package utils; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import java.util.List; /** * Created by Chase on 2017/2/6. */ public class MyFragmentPagerAdapter extends FragmentPagerAdapter { private List fragList; private List tabList; public MyFragmentPagerAdapter(FragmentManager fm, List fragList) { super(fm); this.fragList = fragList; } @Override public CharSequence getPageTitle(int position) { return tabList.get(position); } @Override public Fragment getItem(int position) { return fragList.get(position); } @Override public int getCount() { return fragList.size(); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 现在三个Fragment已经添加到了MainActivity中,滑动ViewPager切换Fragment,同时底部的导航栏也会切换,在为ViewPager添加监听以前,先说说底部导航栏。 第二步,底部导航。 这个的切换其实就是切换准备好的png图片和改变文字的颜色。 下面是刚才导入的底部导航栏xml文件: <?xml version="1.0" encoding="utf-8"?> <FrameLayout android:id="@+id/fl_page_home" android:layout_width="wrap_content" android:layout_height="57dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> </FrameLayout> <FrameLayout android:id="@+id/fl_page_budget" android:layout_width="wrap_content" android:layout_height="57dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> </FrameLayout> <FrameLayout android:id="@+id/fl_page_more" android:layout_width="wrap_content" android:layout_height="57dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> </FrameLayout> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 继续回到对应的MainActivity:并加入了按两次回退键退出程序。 package activity; import ... public class MainActivity extends FragmentActivity implements View.OnClickListener { private ViewPager mViewPager; private MyFragmentPagerAdapter mAdapter; private List fragmentList; //保存界面的view private FrameLayout fl_page_home, fl_page_budget, fl_page_more; private LinearLayout ll_taball; private Button bt_page_home, bt_page_budget, bt_page_more; private TextView tv_page_home; private TextView tv_page_budget; private TextView tv_page_more; private TextView tv_top_title; //onkeydown_ private static boolean isQuit = false; private Timer timer = new Timer(); //onResult的码 private static final int addActivityRequestCodeOfPage2 = 0,addActivityRequestCodeOfPage1=1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); StatusBarUtil.setWindowStatusBarColor(this, R.color.colorTitleGray); initViews(); setViewPagerEvent(); initEvents(); initDatas(); } @Override protected void onRestart() { super.onRestart(); } /** * viewPager切换页面的事件 */ private void setViewPagerEvent() { //设置viewpager的page监听换bottom按钮颜色 mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { int currentItem = mViewPager.getCurrentItem(); switch (currentItem) { case 0: resetImgAndTextColorAndButton(); bt_page_home.setBackgroundResource(R.drawable.home_pressed); tv_page_home.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("首页"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_main_top_menu); break; case 1: resetImgAndTextColorAndButton(); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("记录"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_add_button); break; case 2: resetImgAndTextColorAndButton(); bt_page_more.setBackgroundResource(R.drawable.more_pressed); tv_page_more.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("更多"); bt_add.setVisibility(View.INVISIBLE); break; default: break; } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageScrollStateChanged(int state) { } }); } /** * 数据初始化 */ private void initDatas() { //fragment数据源 fragmentList = new ArrayList(); fragmentList.add(new Fragment_tab01()); fragmentList.add(new Fragment_tab02()); fragmentList.add(new Fragment_tab03()); mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentList); mViewPager.setAdapter(mAdapter); } /** * 初始化事件 */ private void initEvents() { fl_page_home.setOnClickListener(this); fl_page_budget.setOnClickListener(this); fl_page_more.setOnClickListener(this); bt_add.setOnClickListener(this); } /** * 初始化控件 */ private void initViews() { mViewPager = (ViewPager) findViewById(R.id.vp_mainvp); //底部的布局 fl_page_home = (FrameLayout) findViewById(R.id.fl_page_home); fl_page_budget = (FrameLayout) findViewById(R.id.fl_page_budget); fl_page_more = (FrameLayout) findViewById(R.id.fl_page_more); //底部的按钮 bt_page_home = (Button) findViewById(R.id.bt_page_home); bt_page_budget = (Button) findViewById(R.id.bt_page_budget); bt_page_more = (Button) findViewById(R.id.bt_page_more); //按钮对应文字的颜色 tv_page_home = (TextView) findViewById(R.id.tv_page_home); tv_page_budget = (TextView) findViewById(R.id.tv_page_budget); tv_page_more = (TextView) findViewById(R.id.tv_page_more); //顶部状态栏文字 tv_top_title = (TextView) findViewById(R.id.tv_top_title); ll_taball = (LinearLayout) findViewById(R.id.ll_taball); //记一笔按钮 bt_add = (Button) findViewById(R.id.bt_add); bt_add.setVisibility(View.VISIBLE); } /** * 点击下面的布局按钮事件 * * @param v */ @Override public void onClick(View v) { resetImgAndTextColorAndButton(); switch (v.getId()) { /** * 底部导航栏按钮 */ case R.id.fl_page_home: mViewPager.setCurrentItem(0);//如果首页 切换首页 bt_page_home.setBackgroundResource(R.drawable.home_pressed);//并将按钮颜色点亮 tv_page_home.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("首页"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_main_top_menu); break; case R.id.fl_page_budget: mViewPager.setCurrentItem(1); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("记录"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_add_button); break; case R.id.fl_page_more: mViewPager.setCurrentItem(2); bt_page_more.setBackgroundResource(R.drawable.more_pressed); tv_page_more.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("更多"); bt_add.setVisibility(View.INVISIBLE); break; default: break; } } /** * 设置所有图片暗色和文字 */ private void resetImgAndTextColorAndButton() { bt_page_home.setBackgroundResource(R.drawable.home); bt_page_budget.setBackgroundResource(R.drawable.budget); bt_page_more.setBackgroundResource(R.drawable.more); tv_page_home.setTextColor(Color.rgb(56, 56, 56)); tv_page_budget.setTextColor(Color.rgb(56, 56, 56)); tv_page_more.setTextColor(Color.rgb(56, 56, 56)); } /** * 回退按钮两次退出 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (isQuit == false) { isQuit = true; ToastUtil.showToast(getApplicationContext(), "请按两次回退键退出", 3000); TimerTask task = null; task = new TimerTask() { @Override public void run() { isQuit = false; } }; timer.schedule(task, 2000); } else { finish(); System.exit(0); } } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == addActivityRequestCodeOfPage2) { mViewPager.setCurrentItem(1); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); }else if (requestCode==addActivityRequestCodeOfPage1){ bt_page_home.setBackgroundResource(R.drawable.home_pressed); tv_page_home.setTextColor(Color.rgb(255, 209, 0)); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 最后加入的onActivityResult是对应如下情况,如果在某个Fragment中对应进去了其他的Activity时,返回以后导航栏是没有之前的显示的,所以如下就要返回原来的显示。 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == addActivityRequestCodeOfPage2) { mViewPager.setCurrentItem(1); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); }else if (requestCode==addActivityRequestCodeOfPage1){ bt_page_home.setBackgroundResource(R.drawable.home_pressed); tv_page_home.setTextColor(Color.rgb(255, 209, 0)); } } 1 2 3 4 5 6 7 8 9 10 11 12 第三步,顶部右上角菜单。 之前导入顶部栏的xml文件: <?xml version="1.0" encoding="utf-8"?> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 对应菜单我们使用PopupWindow 。 package views; import ... /** * Created by Chase on 2017/2/23. */ public class TopPopWindow extends PopupWindow { private View mView; private LinearLayout ll_popmenu_record,ll_popmenu_book,ll_popmenu_search; public TopPopWindow(Activity paramActivity, View.OnClickListener paramOnClickListener, int paramInt1, int paramInt2){ mView = LayoutInflater.from(paramActivity).inflate(R.layout.popwindow_topright, null); ll_popmenu_record = (LinearLayout) mView.findViewById(R.id.ll_popmenu_record); ll_popmenu_book = (LinearLayout) mView.findViewById(R.id.ll_popmenu_book); ll_popmenu_search = (LinearLayout) mView.findViewById(R.id.ll_popmenu_search); if (paramOnClickListener != null){ //设置点击监听 ll_popmenu_record.setOnClickListener(paramOnClickListener); ll_popmenu_book.setOnClickListener(paramOnClickListener); ll_popmenu_search.setOnClickListener(paramOnClickListener); setContentView(mView); //设置宽度 setWidth(paramInt1); //设置高度 setHeight(paramInt2); //设置显示隐藏动画 setAnimationStyle(R.style.AnimTools); //设置背景透明 setBackgroundDrawable(new ColorDrawable(0)); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 编写PopupWindow 的xml: <?xml version="1.0" encoding="utf-8"?> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 回到MainActivity: package activity; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.view.ViewPager; import android.view.KeyEvent; import android.view.View; import android.widget.Button; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; import com.chase.cn.money_of_my.R; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import utils.MyFragmentPagerAdapter; import utils.StatusBarUtil; import utils.ToastUtil; import views.TopPopWindow; public class MainActivity extends FragmentActivity implements View.OnClickListener { private ViewPager mViewPager; private MyFragmentPagerAdapter mAdapter; private List fragmentList; //保存界面的view private FrameLayout fl_page_home, fl_page_budget, fl_page_more; private LinearLayout ll_taball; private Button bt_page_home, bt_page_budget, bt_page_more; private Button bt_add; private TextView tv_page_home; private TextView tv_page_budget; private TextView tv_page_more; private TextView tv_top_title; //onkeydown_ private static boolean isQuit = false; private Timer timer = new Timer(); //onResult的码 private static final int addActivityRequestCodeOfPage2 = 0,addActivityRequestCodeOfPage1=1; private TopPopWindow topPopWindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); StatusBarUtil.setWindowStatusBarColor(this, R.color.colorTitleGray); initViews(); setViewPagerEvent(); initEvents(); initDatas(); } @Override protected void onRestart() { super.onRestart(); } /** * viewPager切换页面的事件 */ private void setViewPagerEvent() { //设置viewpager的page监听换bottom按钮颜色 mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { int currentItem = mViewPager.getCurrentItem(); switch (currentItem) { case 0: resetImgAndTextColorAndButton(); bt_page_home.setBackgroundResource(R.drawable.home_pressed); tv_page_home.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("首页"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_main_top_menu); break; case 1: resetImgAndTextColorAndButton(); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("记录"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_add_button); break; case 2: resetImgAndTextColorAndButton(); bt_page_more.setBackgroundResource(R.drawable.more_pressed); tv_page_more.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("更多"); bt_add.setVisibility(View.INVISIBLE); break; default: break; } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageScrollStateChanged(int state) { } }); } /** * 数据初始化 */ private void initDatas() { //fragment数据源 fragmentList = new ArrayList(); fragmentList.add(new Fragment_tab01()); fragmentList.add(new Fragment_tab02()); fragmentList.add(new Fragment_tab03()); mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentList); mViewPager.setAdapter(mAdapter); } /** * 初始化事件 */ private void initEvents() { fl_page_home.setOnClickListener(this); fl_page_budget.setOnClickListener(this); fl_page_more.setOnClickListener(this); bt_add.setOnClickListener(this); } /** * 初始化控件 */ private void initViews() { mViewPager = (ViewPager) findViewById(R.id.vp_mainvp); //底部的布局 fl_page_home = (FrameLayout) findViewById(R.id.fl_page_home); fl_page_budget = (FrameLayout) findViewById(R.id.fl_page_budget); fl_page_more = (FrameLayout) findViewById(R.id.fl_page_more); //底部的按钮 bt_page_home = (Button) findViewById(R.id.bt_page_home); bt_page_budget = (Button) findViewById(R.id.bt_page_budget); bt_page_more = (Button) findViewById(R.id.bt_page_more); //按钮对应文字的颜色 tv_page_home = (TextView) findViewById(R.id.tv_page_home); tv_page_budget = (TextView) findViewById(R.id.tv_page_budget); tv_page_more = (TextView) findViewById(R.id.tv_page_more); //顶部状态栏文字 tv_top_title = (TextView) findViewById(R.id.tv_top_title); ll_taball = (LinearLayout) findViewById(R.id.ll_taball); //记一笔按钮 bt_add = (Button) findViewById(R.id.bt_add); bt_add.setVisibility(View.VISIBLE); } /** * 点击下面的布局按钮事件 * * @param v */ @Override public void onClick(View v) { resetImgAndTextColorAndButton(); switch (v.getId()) { /** * 底部导航栏按钮 */ case R.id.fl_page_home: mViewPager.setCurrentItem(0);//如果首页 切换首页 bt_page_home.setBackgroundResource(R.drawable.home_pressed);//并将按钮颜色点亮 tv_page_home.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("首页"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_main_top_menu); break; case R.id.fl_page_budget: mViewPager.setCurrentItem(1); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("记录"); bt_add.setVisibility(View.VISIBLE); bt_add.setBackgroundResource(R.drawable.selector_add_button); break; case R.id.fl_page_more: mViewPager.setCurrentItem(2); bt_page_more.setBackgroundResource(R.drawable.more_pressed); tv_page_more.setTextColor(Color.rgb(255, 209, 0)); tv_top_title.setText("更多"); bt_add.setVisibility(View.INVISIBLE); break; /** * 记一笔按钮 */ case R.id.bt_add: if (mViewPager.getCurrentItem() == 1) { Intent intent_add_activity = new Intent(getApplicationContext(), AddRecorderActivity.class); startActivityForResult(intent_add_activity, addActivityRequestCodeOfPage2); } else { bt_page_home.setBackgroundResource(R.drawable.home_pressed);//并将按钮颜色点亮 tv_page_home.setTextColor(Color.rgb(255, 209, 0)); showTopRightPopMenu(); } break; /** * popwindow引入的方法的onclick的listener引入到this * popwindow的点击事件 */ case R.id.ll_popmenu_record: Intent intent_add_activity = new Intent(getApplicationContext(), AddRecorderActivity.class); startActivityForResult(intent_add_activity,addActivityRequestCodeOfPage1); topPopWindow.dismiss(); break; case R.id.ll_popmenu_book: ToastUtil.showSucceccToast(getApplicationContext(), "success12", 3000); break; case R.id.ll_popmenu_search: ToastUtil.showSucceccToast(getApplicationContext(), "success13", 3000); break; default: break; } } /** * 显示右上角popup菜单 */ private void showTopRightPopMenu() { if (topPopWindow == null) { //(activity,onclicklistener,width,height) topPopWindow = new TopPopWindow(MainActivity.this, this, 360, 290); //监听窗口的焦点事件,点击窗口外面则取消显示 topPopWindow.getContentView().setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { topPopWindow.dismiss(); } } }); } //设置默认获取焦点 topPopWindow.setFocusable(true); //以某个控件的x和y的偏移量位置开始显示窗口 topPopWindow.showAsDropDown(bt_add, 0, 0); //如果窗口存在,则更新 topPopWindow.update(); } /** * 设置所有图片暗色和文字 */ private void resetImgAndTextColorAndButton() { bt_page_home.setBackgroundResource(R.drawable.home); bt_page_budget.setBackgroundResource(R.drawable.budget); bt_page_more.setBackgroundResource(R.drawable.more); tv_page_home.setTextColor(Color.rgb(56, 56, 56)); tv_page_budget.setTextColor(Color.rgb(56, 56, 56)); tv_page_more.setTextColor(Color.rgb(56, 56, 56)); } /** * 回退按钮两次退出 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (isQuit == false) { isQuit = true; ToastUtil.showToast(getApplicationContext(), "请按两次回退键退出", 3000); TimerTask task = null; task = new TimerTask() { @Override public void run() { isQuit = false; } }; timer.schedule(task, 2000); } else { finish(); System.exit(0); } } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == addActivityRequestCodeOfPage2) { mViewPager.setCurrentItem(1); bt_page_budget.setBackgroundResource(R.drawable.budget_pressed); tv_page_budget.setTextColor(Color.rgb(255, 209, 0)); }else if (requestCode==addActivityRequestCodeOfPage1){ bt_page_home.setBackgroundResource(R.drawable.home_pressed); tv_page_home.setTextColor(Color.rgb(255, 209, 0)); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 右上角的按钮还添加了功能,在不同的Fragment中,它的功能不同。 以上就算安卓模仿微信界面的步骤了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值