Android自定義組件(一)瀏覽器
名稱
|
效果
|
屬性
|
Loading動態...的效果組件
|
loading...的動態效果
|
定義了以下四屬性:
1)loadImage:load字圖片,reference類型
2)pointImage:小點圖片,reference類型
3)pointCount:小點數目,integer類型
4)msecRate:毫秒級變化速率,integer類型
|
Title背景移位的效果組件
|
集合View佈局,造成標題欄。實現了標題項下的背景移動的小效果。
|
定義了以下屬性:
1)titleLayout:標題欄佈局
2)bgImage:item背景圖片
3)bgLeftMargin:背景初始左邊距
4)animTime:移動動畫時間
|
ViewPager綁定標題的效果組件
|
ViewPager綁定標題欄,並實現了標題項下的背景移動的小效果。
|
效果特徵以下:
1)背景隨ViewPager滾動而同步在標題間滾動
2)點擊標題時,ViewPager程序控制滾動&背景同步
屬性定義以下:
1)tLayout:標題欄佈局
2)bImage:item背景圖片
3)bMargin:背景初始左邊距
|
ListView增長抽屜的效果組件
|
ListView增長抽屜的效果組件。抽屜打開的界面只用了一個。
|
1)listViewId:列表視圖id,reference類型
2)drawerContent:抽屜內容視圖id,reference類型
3)drawerClose:抽屜內容的關閉按鈕id,reference類型
|
自定義能隱藏更多標題的組件
|
集合View佈局,造成標題欄。實現超過標題數限制時,自動顯示更多的效果。
|
初始化時,須要進行以下步驟:
1)設置顯示數限制,默認將爲6。
2)綁定標題內容。爲String[],將直接以TextView顯示==
3)綁定更多操做的視圖id。將本身加載,併爲其設置點擊事件。
4)綁定更多顯示的視圖。應爲已有的ViewGroup。將自動加載超出限制的標題內容(TextView)。更多操做則將控制其顯示或隱藏。
另外,提供刷新內容的方法,用於:1、標題欄內容的從新加載;二,更多顯示內容的從新加載。
|
自繪實時動態數據線
|
利用View繪製的實時數據顯示組件?
|
寫該文檔時才挪進來的了,感受弄得亂亂的。
雙點縮放好像很不正確啊?應該是兩個觸摸點沒弄對,得到的是一個手指頭觸發的兩個點,因此一下放大了。(猜想,總之我是不修了^^)
|
- <!-- TitleViewPager -->
- <declare-styleable name="TitleViewPager">
- <attr format="reference" name="tLayout" />
- <attr format="reference" name="bImage" />
- <attr format="integer" name="bMargin" />
- </declare-styleable>
- <item name="containerLayout" type="id"/>
- public class TitleViewPager extends RelativeLayout implements
- OnPageChangeListener, View.OnClickListener {
- private Context mContext; // 上下文
- private LayoutInflater mInflater; // 佈局加載器
- private int titleLayoutId; // 標題欄佈局id
- private int bgImageResId; // item背景圖片資源id
- private int bgLeftMargin; // 背景初始左邊距
- private View titleLayout; // 標題欄佈局
- private ImageView mBgImage; // item背景圖片
- private ArrayList<View> mItemViews; // 標題項視圖集合
- private ViewPager mViewPager; // ViewPager組件
- private ArrayList<View> mPageViews; // 頁面視圖集合
- private int prevOffset = -1; // 前次偏移值,這裏用了int值像素
- private int currentIndex; // 當前頁面索引
- private int previousIndex; // 前次頁面索引
- private boolean isTitleClicked; // 標題項點擊
- private OnPageChangeListener mOnPageChangeListener; // 頁面變化監聽事件
- // private final int REFRESH_RATE = 20; // 刷新速率20msec
- // private Scroller mScroller; // 滾動器
- // private static final Interpolator sInterpolator = new Interpolator() {
- // public float getInterpolation(float t) {
- // t -= 1.0f;
- // return t * t * t + 1.0f;
- // }
- // };
- public TitleViewPager(Context context, AttributeSet attrs) {
- super(context, attrs);
- mContext = context;
- mInflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- // 得到TypedArray對象
- TypedArray typedArray = context.obtainStyledAttributes(attrs,
- R.styleable.TitleViewPager);
- // 獲取標題欄佈局id,默認0
- titleLayoutId = typedArray.getResourceId(
- R.styleable.TitleViewPager_tLayout, 0);
- // 獲取item背景圖片資源id,默認0
- bgImageResId = typedArray.getResourceId(
- R.styleable.TitleViewPager_bImage, 0);
- // 獲取背景初始左邊距,默認0
- bgLeftMargin = typedArray.getInt(R.styleable.TitleViewPager_bMargin, 0);
- initLayout(); // 初始化標題欄&ViewPager
- mItemViews = new ArrayList<View>();
- mPageViews = new ArrayList<View>();
- }
- // 初始化標題欄&ViewPager
- private void initLayout() {
- RelativeLayout containerLayout = new RelativeLayout(mContext); // 建立標題欄容器佈局
- containerLayout.setId(R.id.containerLayout); // 設置標識符
- LayoutParams containerParams = new LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); // 寬度WRAP_CONTENT,高度WRAP_CONTENT
- containerParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
- RelativeLayout.TRUE); // 貼於頂部
- containerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
- RelativeLayout.TRUE); // 水平居中
- addView(containerLayout, containerParams); // 當前佈局增長容器佈局
- if (0 != bgImageResId) {
- mBgImage = new ImageView(mContext); // 建立item背景圖片
- mBgImage.setImageResource(bgImageResId); // 設置item背景圖片
- LayoutParams p_w_picpathParams = new LayoutParams(
- LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); // 寬度WRAP_CONTENT,高度WRAP_CONTENT
- p_w_picpathParams.addRule(RelativeLayout.CENTER_VERTICAL,
- RelativeLayout.TRUE); // 垂直居中
- p_w_picpathParams.leftMargin = bgLeftMargin; // 左邊距
- containerLayout.addView(mBgImage, p_w_picpathParams); // 標題欄容器增長標題item背景圖片
- }
- if (titleLayoutId != 0) {
- titleLayout = mInflater.inflate(titleLayoutId, this, false); // 得到標題欄佈局
- LayoutParams titleParams = new LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); // 寬度WRAP_CONTENT,高度WRAP_CONTENT
- titleParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
- RelativeLayout.TRUE); // 水平居中
- titleParams.addRule(RelativeLayout.CENTER_VERTICAL,
- RelativeLayout.TRUE); // 垂直居中
- containerLayout.addView(titleLayout, titleParams); // 標題欄容器增長標題欄佈局
- }
- mViewPager = new ViewPager(mContext); // 建立ViewPager
- mViewPager.setAdapter(new MPagerAdapter()); // 設置ViewPager適配器
- mViewPager.setOnPageChangeListener(this); // 設置頁面改變的監聽接口
- LayoutParams viewPagerParams = new LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); // 寬度FILL_PARENT,高度FILL_PARENT
- viewPagerParams.addRule(RelativeLayout.BELOW, containerLayout.getId()); // 佈於標題欄容器下方
- viewPagerParams.addRule(RelativeLayout.CENTER_HORIZONTAL,
- RelativeLayout.TRUE); // 水平居中
- addView(mViewPager, viewPagerParams); // 當前佈局增長容器ViewPager
- }
- // 增長一個綁定頁面
- public void addBindedPage(int pageViewId, int titleItemId) {
- mPageViews.add(mInflater.inflate(pageViewId, this, false));
- View item = titleLayout.findViewById(titleItemId);
- item.setOnClickListener(this);
- mItemViews.add(item);
- }
- // 得到頁面數量
- public int getCount() {
- return mPageViews.size();
- }
- // 初始化頁面(須要在UI加載完後,能夠覆寫onWindowFocusChanged())
- public void setPage(int index) {
- setImagePosition(index); // 設置圖像至標題項位置
- mViewPager.setCurrentItem(index, false); // 設置ViewPager當前頁面
- }
- // 設置當前頁面
- public void setCurrentPage(int index, boolean isAnim) {
- previousIndex = currentIndex; // 記錄前次頁面索引
- currentIndex = index; // 設置當前頁面索引
- mViewPager.setCurrentItem(index, isAnim); // 設置ViewPager當前頁面
- // Title移動綁定在ViewPager的滾動事件內
- }
- // 設置圖像至標題項位置
- private void setImagePosition(int index) {
- previousIndex = currentIndex; // 記錄前次頁面索引
- currentIndex = index; // 設置當前頁面索引
- if (null == mBgImage) {
- return;
- }
- LayoutParams params = (RelativeLayout.LayoutParams) mBgImage
- .getLayoutParams(); // 得到圖片佈局
- View item = mItemViews.get(index); // 標題項
- // 注:UI加載完後getLeft()纔有值
- int targetLeftMargin = (int) (item.getLeft() + item.getWidth() / 2.0 - mBgImage
- .getWidth() / 2.0); // 目標左邊距
- // 位置未變時直接返回,以免屢次setLayoutParams(...)
- if (params.leftMargin == targetLeftMargin) {
- return;
- }
- params.leftMargin = targetLeftMargin;
- mBgImage.setLayoutParams(params); // 使設置生效
- }
- // 設置圖像移動像素距離
- private void moveImagePosition(int offset) {
- if (null == mBgImage) {
- return;
- }
- LayoutParams params = (RelativeLayout.LayoutParams) mBgImage
- .getLayoutParams(); // 得到圖片佈局
- params.leftMargin += offset;
- mBgImage.setLayoutParams(params); // 使設置生效
- }
- /*
- * 當前頁滾動時調用,不管是程序控制的平滑滾動仍是用戶發起的觸摸滾動。
- * arg0:第一個頁面當前顯示的位置索引。若是頁面偏移不是0,下一個頁面將會可見。
- * arg1:表示第二個頁面位置偏移量的比例值,[0, 1)。(右側頁面所佔屏幕百分比)
- * arg2:表示第二個頁面位置偏移量的像素值。(右側頁面距右邊的像素值)
- */
- @Override
- public void onPageScrolled(int position, float positionOffset,
- int positionOffsetPixels) {
- // 判斷是否不在動畫,用positionOffsetPixels判斷判斷緣由是:
- // 1)position,在選中了頁面時就會改變,自動動畫時的不能判斷
- // 2)positionOffset,動畫完變爲0.0,但float很差直接等於判斷
- // 3)positionOffsetPixels,動畫完變爲0,int型^^
- if (positionOffsetPixels == 0) {
- setImagePosition(position);
- prevOffset = -1;
- isTitleClicked = false;
- return;
- }
- // 剛移動時,記錄下該次值
- if (prevOffset == -1) {
- prevOffset = positionOffsetPixels;
- return;
- }
- int pageOffset = positionOffsetPixels - prevOffset; // 頁面偏移距離
- prevOffset = positionOffsetPixels;
- if (null != mBgImage) {
- try {
- if (pageOffset < 0) { // 左->右
- int prevIndex, nextIndex;
- if (isTitleClicked) {
- prevIndex = previousIndex;
- nextIndex = currentIndex;
- } else {
- prevIndex = currentIndex;
- nextIndex = currentIndex - 1;
- }
- // 兩菜單項間的距離
- int itemDistance = mItemViews.get(prevIndex).getLeft()
- - mItemViews.get(nextIndex).getLeft();
- // 圖片偏移距離
- int p_w_picpathOffset = pageOffset * itemDistance
- / mViewPager.getWidth();
- // 設置圖像移動像素距離
- moveImagePosition(p_w_picpathOffset);
- } else if (pageOffset > 0) { // 右->左
- int prevIndex, nextIndex;
- if (isTitleClicked) {
- prevIndex = previousIndex;
- nextIndex = currentIndex;
- } else {
- prevIndex = currentIndex;
- nextIndex = currentIndex + 1;
- }
- // 兩菜單項間的距離
- int itemDistance = mItemViews.get(nextIndex).getLeft()
- - mItemViews.get(prevIndex).getLeft();
- // 圖片偏移距離
- int p_w_picpathOffset = pageOffset * itemDistance
- / mViewPager.getWidth();
- // 設置圖像移動像素距離
- moveImagePosition(p_w_picpathOffset);
- }
- } catch (IndexOutOfBoundsException e) {
- // 相似在中間左右左右的來回拖拽==,判斷還不夠啊T^T
- setImagePosition(currentIndex);
- isTitleClicked = false;
- }
- }
- if (null != mOnPageChangeListener) {
- mOnPageChangeListener.onPageScrolled(position, positionOffset,
- positionOffsetPixels);
- }
- }
- /*
- * 當一個新頁面被選中時被調用。動畫不必定必須完成。
- * arg0:新選中頁面的位置索引
- */
- @Override
- public void onPageSelected(int position) {
- if (null != mOnPageChangeListener) {
- mOnPageChangeListener.onPageSelected(position);
- }
- }
- /*
- * 滾動狀態改變時調用。用於發現用戶什麼時候開始拖動、頁面什麼時候自動沉降到當前頁(用戶不拖動時)、或者什麼時候徹底中止/空閒。
- * arg0:新的滾動狀態。SCROLL_STATE_DRAGGING、SCROLL_STATE_SETTLING、SCROLL_STATE_IDLE
- */
- @Override
- public void onPageScrollStateChanged(int state) {
- if (state == ViewPager.SCROLL_STATE_DRAGGING) { // 用戶拖動時
- isTitleClicked = false;
- }
- if (null != mOnPageChangeListener) {
- mOnPageChangeListener.onPageScrollStateChanged(state);
- }
- }
- // 自定義的ViewPager適配器
- private class MPagerAdapter extends PagerAdapter {
- /*
- * 移除一個給定位置的頁面。適配器有責任從它的容器中移除視圖,雖然這僅必須確認動做是在finishUpdate()後按時間完成的。
- * arg0:容器視圖,從中將移除頁面。
- * arg1:移除的頁面位置
- * arg2:和instantiateItem(View, int)返回的同樣的對象
- */
- @Override
- public void destroyItem(View arg0, int arg1, Object arg2) {
- ((ViewPager) arg0).removeView(mPageViews.get(arg1));
- }
- /*
- * 當顯示的界面完成變化後調用。在這裏,你應當必須確保全部的頁面已經真正的從容器中增長或刪除。
- * arg0:容器視圖,用於顯示適配器的頁面視圖
- */
- @Override
- public void finishUpdate(View arg0) {
- }
- // 返回可用界面的數量
- @Override
- public int getCount() {
- return mPageViews.size();
- }
- /*
- * 建立一個給定位置的界面。適配器有責任給這邊給出的容器增長一個視圖,雖然這僅必須確認動做是在finishUpdate()後按時間完成的。
- * arg0:容器視圖,在裏面將顯示頁面。
- * arg1:要被裝載的頁面位置
- * Object:返回一個展示新畫面的對象。這沒必要須是一個View,也能夠是一些其餘的頁面容器。
- */
- @Override
- public Object instantiateItem(View arg0, int arg1) {
- ((ViewPager) arg0).addView(mPageViews.get(arg1), 0);
- return mPageViews.get(arg1);
- }
- // 是不是由對象生成的視圖
- @Override
- public boolean isViewFromObject(View arg0, Object arg1) {
- return arg0 == (arg1);
- }
- // 恢復狀態
- @Override
- public void restoreState(Parcelable arg0, ClassLoader arg1) {
- }
- // 保存狀態,返回序列化對象
- @Override
- public Parcelable saveState() {
- return null;
- }
- /*
- * 當顯示的頁面將要開始變化時調用
- * arg0:容器視圖,用於顯示適配器的頁面視圖
- */
- @Override
- public void startUpdate(View arg0) {
- }
- }
- @Override
- public void onClick(View v) {
- int size = mItemViews.size(); // 大小
- for (int i = 0; i < size; i++) {
- if (mItemViews.get(i).getId() == v.getId()) {
- isTitleClicked = true;
- setCurrentPage(i, true);
- break;
- }
- }
- }
- // 得到標題項視圖集合
- public ArrayList<View> getItemViews() {
- return mItemViews;
- }
- // 得到 頁面視圖集合
- public ArrayList<View> getPageViews() {
- return mPageViews;
- }
- // 設置頁面變化監聽事件
- public void setOnPageChangeListener(OnPageChangeListener listener) {
- mOnPageChangeListener = listener;
- }
- }