Android自定义控件——Indicator
来源:互联网 发布:大数据平台定义及功能 编辑:程序博客网 时间:2024/06/05 09:53
Indicator确实是个老梗了...
有重写HorizontalScrollView的,有重写LinearLayout。
这个是重写LinearLayout的哦,往LinearLayout里add TextView用作tab标签,在LinearLayout底部画一个矩形当作指示器。
ViewPager滚动的时候用简单的小学加减乘除混合运算来机选这个矩形位置,然后滚动就好了
属性
<?xml version="1.0" encoding="utf-8"?><resources> <attr name="tab_color_normal" format="color" /> <attr name="tab_color_light" format="color" /> <attr name="cursor_color" format="color" /> <attr name="cursor_height" format="dimension" /> <declare-styleable name="Indicator"> <attr name="tab_color_normal" /> <attr name="tab_color_light" /> <attr name="cursor_color" /> <attr name="cursor_height" /> </declare-styleable></resources>
Indicator.java 关键的地方都谢了注释
package com.mingwei.indicator.view;import java.util.List;import android.annotation.TargetApi;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Rect;import android.os.Build;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.AttributeSet;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.widget.HorizontalScrollView;import android.widget.LinearLayout;import android.widget.TextView;import com.mingwei.indicator.R;@TargetApi(Build.VERSION_CODES.HONEYCOMB)public class Indicator extends LinearLayout implements OnClickListener, OnPageChangeListener {/** * 绘制时用的画笔 */private Paint mPaint;/** * 默认颜色 */private int mCursorColor;/** * 滚动的指示器的矩形范围 */private Rect mRect = new Rect();/** * 滚动游标的绘制范围 */private int mL, mR, mT, mB;/** * 最多可见的游标数 */private int mVisiableTabCount = 4;/** * 游标高度 */private int mCursorHeight = 6;/** * tab的宽度 */private int mTabWidth;/** * 选中和非选中状态的标签文字颜色 */private int mTabColorNormal;private int mTabColorLight;/** * 水平滚动的距离 */private float mTranslationX;/** * 需要监听ViewPager动作来跟新游标 */private ViewPager mViewPager;public Indicator(Context context) {this(context, null);}public Indicator(Context context, AttributeSet attrs) {this(context, attrs, 0);}public Indicator(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initAttr(context, attrs, defStyleAttr);mPaint = new Paint();mPaint.setColor(mCursorColor);mPaint.setAntiAlias(true);mPaint.setStyle(Style.FILL);}private void initAttr(Context context, AttributeSet attrs, int defStyleAttr) {TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Indicator);mTabColorNormal = array.getColor(R.styleable.Indicator_tab_color_normal, Color.BLACK);mTabColorLight = array.getColor(R.styleable.Indicator_tab_color_light, Color.WHITE);mCursorColor = array.getColor(R.styleable.Indicator_cursor_color, Color.BLACK);mCursorHeight = array.getDimensionPixelSize(R.styleable.Indicator_cursor_height, mCursorHeight);array.recycle();}@Overrideprotected void onFinishInflate() {super.onFinishInflate();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);int count = getChildCount();if (count == 0) {return;}mTabWidth = getWidth() / mVisiableTabCount;for (int i = 0; i < count; i++) {View view = getChildAt(i);LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();params.weight = 0;params.width = mTabWidth;params.height = getHeight() - mCursorHeight;view.setLayoutParams(params);}mL = 0;mT = getHeight() - mCursorHeight;mR = mTabWidth;mB = getHeight();mRect = new Rect(mL, mT, mR, mB);}@Overrideprotected void dispatchDraw(Canvas canvas) {super.dispatchDraw(canvas);canvas.save();canvas.translate(mTranslationX, 0);canvas.drawRect(mRect, mPaint);canvas.restore();}private void scroll(int position, float offset) {mTranslationX = getWidth() / mVisiableTabCount * (position + offset);/** * 当tab数大于可见数目的时候,整个容器滚动 */if (getChildCount() > mVisiableTabCount && offset > 0 && (position >= mVisiableTabCount - 2)) {if (mVisiableTabCount != 1) {/** * 当tab等于可见数目不是倒数第二个时滚动容器,否则仍然滚动游标 */if (position != getChildCount() - 2) {scrollTo((position - (mVisiableTabCount - 2)) * mTabWidth + (int) (offset * mTabWidth), 0);}} else {scrollTo(position * mTabWidth + (int) (offset * mTabWidth), 0);}}invalidate();}public void setViewPager(ViewPager viewPager) {mViewPager = viewPager;mViewPager.setOnPageChangeListener(this);}public void setTabs(String[] tabs) {removeAllViews();for (String t : tabs) {createChild(t);}TextView view = (TextView) getChildAt(0);view.setTextColor(mTabColorLight);}public void setTabs(List<String> tabs) {removeAllViews();for (String t : tabs) {createChild(t);}TextView view = (TextView) getChildAt(0);view.setTextColor(mTabColorLight);}private void setTabLight(int arg0) {int count = getChildCount();for (int i = 0; i < count; i++) {TextView view = (TextView) getChildAt(i);if (i == arg0) {view.setTextColor(mTabColorLight);} else {view.setTextColor(mTabColorNormal);}}}/** * 创建子View * * @param text */private void createChild(String text) {TextView view = new TextView(getContext());view.setText(text);view.setGravity(Gravity.CENTER);view.setTextColor(mTabColorNormal);view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);view.setOnClickListener(this);view.setTag(getChildCount());addView(view);}@Overridepublic void onPageScrollStateChanged(int arg0) {}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {scroll(arg0, arg1);}@Overridepublic void onPageSelected(int arg0) {setTabLight(arg0);}@Overridepublic void onClick(View arg0) {int i = (Integer) arg0.getTag();mViewPager.setCurrentItem(i);}}
XML使用
<LinearLayout 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" android:orientation="vertical" > <com.mingwei.indicator.view.Indicator xmlns:ming="http://schemas.android.com/apk/res-auto" android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="45dp" android:orientation="horizontal" ming:cursor_color="@color/indicator_color" ming:cursor_height="3dp" ming:tab_color_light="@color/tab_color_checked" ming:tab_color_normal="@color/tab_color_normal" > </com.mingwei.indicator.view.Indicator> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager></LinearLayout>
package com.mingwei.indicator;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.view.Menu;import android.view.MenuItem;import com.mingwei.indicator.view.Indicator;public class MainActivity extends FragmentActivity {private ViewPager mViewPager;private List<Fragment> mFragments = new ArrayList<Fragment>();private FragmentPagerAdapter mAdapter;private List<String> mStrings = Arrays.asList("标签1", "标签2", "标签3", "标签4", "标签5");private Indicator mIndicator;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {for (String tabs : mStrings) {SimpleFragment fragment = SimpleFragment.newInstance(tabs);mFragments.add(fragment);}mViewPager = (ViewPager) findViewById(R.id.viewpager);mIndicator = (Indicator) findViewById(R.id.indicator);mIndicator.setTabs(mStrings);mIndicator.setViewPager(mViewPager);mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {@Overridepublic int getCount() {return mFragments.size();}@Overridepublic Fragment getItem(int position) {return mFragments.get(position);}};mViewPager.setAdapter(mAdapter);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic 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();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}}
SimpleFragment
package com.mingwei.indicator;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class SimpleFragment extends Fragment {public static final String TITLE = "title";private View mContentView;private TextView mTitle;public static SimpleFragment newInstance(String title) {Bundle bundle = new Bundle();bundle.putString(TITLE, title);SimpleFragment fragment = new SimpleFragment();fragment.setArguments(bundle);return fragment;}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContentView = LayoutInflater.from(getActivity()).inflate(R.layout.simple_fragment, null);mTitle = (TextView) mContentView.findViewById(R.id.simple_fragment_title);Bundle bundle = getArguments();mTitle.setText(bundle.getString(TITLE));}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return mContentView;}@Overridepublic void onDestroyView() {super.onDestroyView();ViewGroup viewGroup = (ViewGroup) mContentView.getParent();if (viewGroup != null) {viewGroup.removeAllViewsInLayout();}}}
1、TextView大小不受控制了,准确的说onSizeChange中的设置TextView的大小的代码无效,
2、ViewPager滑动的过程中卡住,是界面卡住了,强行继续拖拽还能拖过去。
下载地址:http://download.csdn.net/detail/u013045971/9321099
Github:https://github.com/Mingwei360/viewpager_indicator
0 0
- 【Android】自定义控件——仿天猫Indicator
- Android自定义控件——Indicator
- 自定义控件Indicator
- Android自定义控件--无限轮播Banner和Indicator实现
- IOS开发之——自定义的Activity Indicator View
- IOS开发之——自定义的Activity Indicator View
- 自定义Indicator
- Android自定义View之导航指示Indicator
- android上FragmentTabHost实现自定义Tab Indicator
- Android自定义控件——组合控件
- Android自定义控件——自定义属性
- Android 自定义控件——自定义属性
- android 自定义控件 —— 自定义属性
- Android自定义控件——自定义属性
- Android自定义控件——自定义属性
- Android自定义控件——自定义Preference
- Android自定义控件——自定义属性
- Android自定义控件——自定义属性
- 什么是软件性能?
- 详解C#中的反射
- 《leetCode》:Partition List
- java 物理分页和逻辑分页
- Factorial Trailing Zeroes
- Android自定义控件——Indicator
- iOS委托理解
- JAVA——实现多线程
- 第一个hadoop程序_[过程和问题清单]
- 03-加入苹果开发者计划
- Linux 汇编语言(GNU GAS汇编)开发指南
- C#客户端连接C++服务器 目标机器积极拒绝
- Android存储访问与Environment类
- Nginx工作原理和优化、漏洞