-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
N/A Signed-off-by: wuyexiong [伍业雄] <[email protected]>
- Loading branch information
wuyexiong [伍业雄]
committed
Apr 25, 2015
1 parent
36e3724
commit 367d1c2
Showing
40 changed files
with
952 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,9 @@ proguard/ | |
|
||
# Log Files | ||
*.log | ||
|
||
/local.properties | ||
/.idea/workspace.xml | ||
/.idea/libraries | ||
.DS_Store | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
apply plugin: 'com.android.application' | ||
|
||
android { | ||
compileSdkVersion 22 | ||
buildToolsVersion "22.0.1" | ||
|
||
defaultConfig { | ||
applicationId "com.wuyexiong.wechatlikebottomtabui" | ||
minSdkVersion 16 | ||
targetSdkVersion 22 | ||
versionCode 1 | ||
versionName "1.0" | ||
} | ||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
compile fileTree(dir: 'libs', include: ['*.jar']) | ||
compile 'com.android.support:appcompat-v7:22.0.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Add project specific ProGuard rules here. | ||
# By default, the flags in this file are appended to flags specified | ||
# in /Users/wuyexiong/Android/android-sdk-macosx/tools/proguard/proguard-android.txt | ||
# You can edit the include path and order by changing the proguardFiles | ||
# directive in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# Add any project specific keep options here: | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} |
14 changes: 14 additions & 0 deletions
14
app/src/androidTest/java/com/wuyexiong/wechatlikebottomtabui/ApplicationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.wuyexiong.wechatlikebottomtabui; | ||
|
||
import android.app.Application; | ||
import android.test.ApplicationTestCase; | ||
|
||
/** | ||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> | ||
*/ | ||
public class ApplicationTest extends ApplicationTestCase<Application> { | ||
|
||
public ApplicationTest() { | ||
super(Application.class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.wuyexiong.wechatlikebottomtabui" > | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:theme="@style/AppTheme" > | ||
<activity | ||
android:name=".MainActivity" | ||
android:label="@string/app_name" > | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
78 changes: 78 additions & 0 deletions
78
app/src/main/java/com/wuyexiong/wechatlikebottomtabui/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package com.wuyexiong.wechatlikebottomtabui; | ||
|
||
import android.os.Bundle; | ||
import android.support.v4.app.Fragment; | ||
import android.support.v4.view.ViewPager; | ||
import android.support.v7.app.ActionBarActivity; | ||
import android.view.LayoutInflater; | ||
import android.view.Menu; | ||
import android.view.MenuItem; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
|
||
public class MainActivity extends ActionBarActivity { | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_main); | ||
if (savedInstanceState == null) { | ||
getSupportFragmentManager().beginTransaction() | ||
.add(R.id.container, new PlaceholderFragment()) | ||
.commit(); | ||
} | ||
} | ||
|
||
|
||
@Override | ||
public boolean onCreateOptionsMenu(Menu menu) { | ||
// Inflate the menu; this adds items to the action bar if it is present. | ||
getMenuInflater().inflate(R.menu.menu_main, menu); | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean onOptionsItemSelected(MenuItem item) { | ||
// Handle action bar item clicks here. The action bar will | ||
// automatically handle clicks on the Home/Up button, so long | ||
// as you specify a parent activity in AndroidManifest.xml. | ||
int id = item.getItemId(); | ||
|
||
//noinspection SimplifiableIfStatement | ||
if (id == R.id.action_settings) { | ||
return true; | ||
} | ||
|
||
return super.onOptionsItemSelected(item); | ||
} | ||
|
||
/** | ||
* A placeholder fragment containing a simple view. | ||
*/ | ||
public static class PlaceholderFragment extends Fragment { | ||
|
||
private TestFragmentAdapter mAdapter; | ||
private ViewPager mPager; | ||
private MainBottomTabLayout mTabLayout; | ||
|
||
public PlaceholderFragment() { | ||
} | ||
|
||
@Override | ||
public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||
Bundle savedInstanceState) { | ||
View rootView = inflater.inflate(R.layout.fragment_main, container, false); | ||
setupViews(rootView); | ||
return rootView; | ||
} | ||
|
||
private void setupViews(View view) { | ||
mAdapter = new TestFragmentAdapter(getFragmentManager()); | ||
mPager = (ViewPager) view.findViewById(R.id.tab_pager); | ||
mPager.setAdapter(mAdapter); | ||
mTabLayout = (MainBottomTabLayout) view.findViewById(R.id.main_bottom_tablayout); | ||
mTabLayout.setViewPager(mPager); | ||
} | ||
} | ||
} |
208 changes: 208 additions & 0 deletions
208
app/src/main/java/com/wuyexiong/wechatlikebottomtabui/MainBottomTabLayout.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
package com.wuyexiong.wechatlikebottomtabui; | ||
|
||
import android.animation.ArgbEvaluator; | ||
import android.content.Context; | ||
import android.graphics.Canvas; | ||
import android.support.v4.view.PagerAdapter; | ||
import android.support.v4.view.ViewPager; | ||
import android.util.AttributeSet; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.widget.LinearLayout; | ||
import android.widget.TextView; | ||
|
||
/** | ||
* Created by wuyexiong on 4/25/15. | ||
*/ | ||
public class MainBottomTabLayout extends LinearLayout { | ||
|
||
private ViewPager mViewPager; | ||
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener; | ||
|
||
private ArgbEvaluator mColorEvaluator; | ||
int mTextNormalColor, mTextSelectedColor; | ||
|
||
private int mLastPosition; | ||
private int mSelectedPosition; | ||
private float mSelectionOffset; | ||
|
||
private String mTitles[] = {"微信", "通讯录", "发现", "我"}; | ||
private int mIconRes[][] = { | ||
{R.drawable.icon_main_home_normal, R.drawable.icon_main_home_selected}, | ||
{R.drawable.icon_main_category_normal, R.drawable.icon_main_category_selected}, | ||
{R.drawable.icon_main_service_normal, R.drawable.icon_main_service_selected}, | ||
{R.drawable.icon_main_mine_normal, R.drawable.icon_main_mine_selected} | ||
}; | ||
|
||
private View[] mIconLayouts; | ||
|
||
public MainBottomTabLayout(Context context) { | ||
this(context, null); | ||
} | ||
|
||
public MainBottomTabLayout(Context context, AttributeSet attrs) { | ||
this(context, attrs, 0); | ||
} | ||
|
||
public MainBottomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { | ||
super(context, attrs, defStyleAttr); | ||
init(context, attrs, defStyleAttr); | ||
} | ||
|
||
private void init(Context context, AttributeSet attrs, int defStyleAttr) { | ||
mColorEvaluator = new ArgbEvaluator(); | ||
mTextNormalColor = getResources().getColor(R.color.main_bottom_tab_textcolor_normal); | ||
mTextSelectedColor = getResources().getColor(R.color.main_bottom_tab_textcolor_selected); | ||
} | ||
|
||
public void setViewPager(ViewPager viewPager) { | ||
removeAllViews(); | ||
mViewPager = viewPager; | ||
if (viewPager != null && viewPager.getAdapter() != null) { | ||
viewPager.setOnPageChangeListener(new InternalViewPagerListener()); | ||
populateTabLayout(); | ||
} | ||
} | ||
|
||
private void populateTabLayout() { | ||
final PagerAdapter adapter = mViewPager.getAdapter(); | ||
final OnClickListener tabClickListener = new TabClickListener(); | ||
mIconLayouts = new View[adapter.getCount()]; | ||
|
||
for (int i = 0; i < adapter.getCount(); i++) { | ||
|
||
final View tabView = LayoutInflater.from(getContext()).inflate(R.layout.layout_mainbottom_tab, this, false); | ||
mIconLayouts[i] = tabView; | ||
TabIconView iconView = (TabIconView) tabView.findViewById(R.id.main_bottom_tab_icon); | ||
iconView.init(mIconRes[i][0], mIconRes[i][1]); | ||
TextView textView = (TextView) tabView.findViewById(R.id.main_bottom_tab_text); | ||
textView.setText(mTitles[i]); | ||
|
||
if (tabView == null) { | ||
throw new IllegalStateException("tabView is null."); | ||
} | ||
|
||
LayoutParams lp = (LayoutParams) tabView.getLayoutParams(); | ||
lp.width = 0; | ||
lp.weight = 1; | ||
|
||
tabView.setOnClickListener(tabClickListener); | ||
addView(tabView); | ||
|
||
if (i == mViewPager.getCurrentItem()) { | ||
iconView.transformPage(0); | ||
tabView.setSelected(true); | ||
textView.setTextColor(mTextSelectedColor); | ||
} | ||
} | ||
} | ||
|
||
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener { | ||
private int mScrollState; | ||
|
||
@Override | ||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { | ||
onViewPagerPageChanged(position, positionOffset); | ||
|
||
if (mViewPagerPageChangeListener != null) { | ||
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels); | ||
} | ||
} | ||
|
||
@Override | ||
public void onPageSelected(int position) { | ||
|
||
for (int i = 0; i < getChildCount(); i++) { | ||
((TabIconView) mIconLayouts[i].findViewById(R.id.main_bottom_tab_icon)) | ||
.transformPage(position == i ? 0 : 1); | ||
((TextView) mIconLayouts[i].findViewById(R.id.main_bottom_tab_text)) | ||
.setTextColor(position == i ? mTextSelectedColor : mTextNormalColor); | ||
} | ||
|
||
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) { | ||
onViewPagerPageChanged(position, 0f); | ||
} | ||
|
||
for (int i = 0, size = getChildCount(); i < size; i++) { | ||
getChildAt(i).setSelected(position == i); | ||
} | ||
|
||
|
||
if (mViewPagerPageChangeListener != null) { | ||
mViewPagerPageChangeListener.onPageSelected(position); | ||
} | ||
} | ||
|
||
@Override | ||
public void onPageScrollStateChanged(int state) { | ||
mScrollState = state; | ||
|
||
if (mViewPagerPageChangeListener != null) { | ||
mViewPagerPageChangeListener.onPageScrollStateChanged(state); | ||
} | ||
} | ||
} | ||
|
||
private void onViewPagerPageChanged(int position, float positionOffset) { | ||
mSelectedPosition = position; | ||
mSelectionOffset = positionOffset; | ||
if (positionOffset == 0f && mLastPosition != mSelectedPosition) { | ||
mLastPosition = mSelectedPosition; | ||
} | ||
invalidate(); | ||
} | ||
|
||
@Override | ||
protected void onDraw(Canvas canvas) { | ||
super.onDraw(canvas); | ||
final int childCount = getChildCount(); | ||
if (childCount > 0) { | ||
if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) { | ||
|
||
View selectedTab = getChildAt(mSelectedPosition); | ||
View nextTab = getChildAt(mSelectedPosition + 1); | ||
|
||
View selectedIconView = ((LinearLayout) selectedTab).getChildAt(0); | ||
View nextIconView = ((LinearLayout) nextTab).getChildAt(0); | ||
|
||
View selectedTextView = ((LinearLayout) selectedTab).getChildAt(1); | ||
View nextTextView = ((LinearLayout) nextTab).getChildAt(1); | ||
|
||
//draw icon alpha | ||
if (selectedIconView instanceof TabIconView && nextIconView instanceof TabIconView) { | ||
((TabIconView) selectedIconView).transformPage(mSelectionOffset); | ||
((TabIconView) nextIconView).transformPage(1 - mSelectionOffset); | ||
} | ||
|
||
//draw text color | ||
Integer selectedColor = (Integer) mColorEvaluator.evaluate(mSelectionOffset, | ||
mTextSelectedColor, | ||
mTextNormalColor); | ||
Integer nextColor = (Integer) mColorEvaluator.evaluate(1 - mSelectionOffset, | ||
mTextSelectedColor, | ||
mTextNormalColor); | ||
|
||
if (selectedTextView instanceof TextView && nextTextView instanceof TextView) { | ||
((TextView) selectedTextView).setTextColor(selectedColor); | ||
((TextView) nextTextView).setTextColor(nextColor); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private class TabClickListener implements OnClickListener { | ||
@Override | ||
public void onClick(View v) { | ||
for (int i = 0; i < getChildCount(); i++) { | ||
if (v == getChildAt(i)) { | ||
mViewPager.setCurrentItem(i, false); | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { | ||
mViewPagerPageChangeListener = listener; | ||
} | ||
} |
Oops, something went wrong.