Android 自定义布局竖向的ViewPager的实现

Android 自定义布局竖向的ViewPager的实现

效果图:

这个自定义控件涉及到的知识点:

自定义ViewGroup中onMeasure和onLayout的写法
弹性滚动Scroller的用法
速度轨迹追踪器VelocityTracker的用法
如何处理滑动事件冲突

dispatchTouchEvent:(外部拦截)告诉此ScrollLayout的父布局,什么时候该拦截触摸事件,什么时候不该拦截触摸事件

onInterceptTouchEvent:(内部拦截)ScrollLayout告诉自己什么时候要拦截内部子View的触摸事件,什么时候不要拦截内部子View的触摸事件

处理触摸滑动的思路:

  1. 先实现布局跟着手指的滑动而滑动 scrollBy
  2. 处理好边界条件(这次的处理边界,仅适用于低速滑动情况下)
  3. 如果是快速滑动VelocityTracker,必须再次考虑边界问题(上面考虑的边界问题不适用于快速滑动情况)
  4. 如果是低速滑动,要根据手指滑动方向和布局滑动的距离一起做判断,来确定,页面该滑动到那个页面,这里用到了弹性滑动Scroller
  5. 难点来了:算法,
//即确定当前显示的子控件的位置,
//确定弹性滑动滑向那个位置
if (Math.abs(velocityY) > criticalVelocityY) {//当手指滑动速度快时,按照速度方向直接翻页
// 重点二、快速滑动时,如何判断当前显示的是第几个控件,并且再次包含边界判断(必须包含边界判断,因为前面的边界判断,只适用于低速滑动时)
if (shouZhiXiangXiaHuaDong) {
if (currentPage > 1) {//★★★★★★★★边界限制,防止滑倒第一个,还继续滑动,注意★(currentPage-2)
mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 2) - getScrollY());
currentPage--;
}
} else {
if (currentPage < childCount) {//★★★★★★★边界限制,防止滑倒最后一个,还继续滑动,注意★currentPage
mScroller.startScroll(0, getScrollY(), 0, childHeight * currentPage - getScrollY());
currentPage++;
}
}
Log.e("eee", currentPage + "");

总结

当要写一个算法时,不要着急试图一下子写出来,这样往往陷入盲目,应该是一步一步地推导,一步一步实现代码,指导最后找到规律,类似于归纳总结、通项公式的方法。

代码如下:(注释很全)

package beautlful.time.com.beautlfultime.view;

import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

/**
 * 注意:此自定义viewgroup只适用于每个子控件为match_parent的情况,其实一般情况也都是这种情况
 * 注意:此自定义viewgroup,没有考虑padding的情况,使用者不要在ScrollerLayout里使用任何padding,否则你看到的不是你想要的,
 * 为了实现padding效果,你可以为ScrollerLayout的外层再套一层线性布局(或其他布局),在外层布局里使用padding值
 * 此自定义viewgroup基于郭霖博客改编,想了解具体实现细节,请参照:
 * Android Scroller完全解析,关于Scroller你所需知道的一切
 * http://blog.csdn.net/guolin_blog/article/details/48719871
 */
public class VerticalViewPager extends ViewGroup {
  int currentPage = 1;

  /**
   * 速度轨迹追踪器
   */
  private VelocityTracker mVelocityTracker;

  /**
   * 此次计算速度你想要的最大值
   */
  private final int mMaxVelocity;

  /**
   * 第一个触点的id, 此时可能有多个触点,但至少一个
   */
  private int mPointerId;

  /**
   * 计算出的竖向滚动速率
   */
  private float velocityY;

  /**
   * 手指横向滑动的速率临界值,大于这个值时,不考虑手指滑动的距离,直接滚动到最左边或者最右边
   */
  private int criticalVelocityY = 2500;

  /**
   * 用于完成滚动操作的实例
   */
  private Scroller mScroller;

  /**
   * 判定为拖动的最小移动像素数
   */
  private int mTouchSlop;

  /**
   * 手机按下时的屏幕坐标
   */
  private float mYDown;

  /**
   * 手机当时所处的屏幕坐标
   */
  private float mYMove;

  /**
   * 上次触发ACTION_MOVE事件时的屏幕坐标
   */
  private float mYLastMove;

  /**
   * 界面可滚动的顶部边界
   */
  private int topBorder;

  /**
   * 界面可滚动的底部边界
   */
  private int bottomBorder;

  /**
   * 子控件的高度(这里每个子控件高度都一样,都是match_parent)
   */
  private int childHeight;

  /**
   * 手指是否是向下滑动
   */
  private boolean shouZhiXiangXiaHuaDong;
  private int childCount;

  public VerticalViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    // 第一步,创建Scroller的实例
    mScroller = new Scroller(context);
    ViewConfiguration configuration = ViewConfiguration.get(context);
    // 获取TouchSlop值
    mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
    //此次计算速度你想要的最大值
    mMaxVelocity = ViewConfiguration.get(context).getMaximumFlingVelocity();
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
      View childView = getChildAt(i);
      // 为ScrollerLayout中的每一个子控件测量大小
      measureChild(childView, widthMeasureSpec, heightMeasureSpec);
    }
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed) {
      /**
       * 当前子控件之前的所有子控件的总宽度
       */
      int preChildViewTotalHeight = 0;
      for (int i = 0; i < childCount; i++) {
        View childView = getChildAt(i);
        // 为ScrollerLayout中的每一个子控件在竖直方向上进行布局
        if (i == 0) {
          childView.layout(
              0,
              0,
              childView.getMeasuredWidth(),
              childView.getMeasuredHeight());

        } else {
          childView.layout(
              0,
              preChildViewTotalHeight,
              childView.getMeasuredWidth(),
              preChildViewTotalHeight + childView.getMeasuredHeight());
        }
        preChildViewTotalHeight += childView.getMeasuredHeight();

      }
      // 初始化上下边界值
      topBorder = getChildAt(0).getTop();
      bottomBorder = getChildAt(getChildCount() - 1).getBottom();

      childHeight = getChildAt(0).getMeasuredHeight();

    }
  }

  private int downX;
  private int downY;

  //    告诉此ScrollLayout的父布局,什么时候该拦截触摸事件,什么时候不该拦截触摸事件
  public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        //让当前ScrollerLayout对应的父控件不要去拦截事件
        getParent().requestDisallowInterceptTouchEvent(true);
        downX = (int) ev.getX();
        downY = (int) ev.getY();
        break;
      case MotionEvent.ACTION_MOVE:
        int moveX = (int) ev.getX();
        int moveY = (int) ev.getY();

        //请求父控件ViewPager拦截触摸事件,ViewPager左右滚动时,不要触发该布局的上下滑动
        if (Math.abs(moveY - downY) < Math.abs(moveX - downX)) {
          getParent().requestDisallowInterceptTouchEvent(false);
        } else {
          //请求父控件ViewPager不要拦截触摸事件,ScrollerLayout自己可以上下滑动
          getParent().requestDisallowInterceptTouchEvent(true);
        }

        break;

      case MotionEvent.ACTION_CANCEL:

        break;
      case MotionEvent.ACTION_UP:

        break;
    }
    return super.dispatchTouchEvent(ev);
  }

  //   ScrollLayout告诉自己什么时候要拦截内部子View的触摸事件,什么时候不要拦截内部子View的触摸事件
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        //▲▲▲1.求第一个触点的id, 此时可能有多个触点,但至少一个
        mPointerId = ev.getPointerId(0);
        mYDown = ev.getRawY();
        mYLastMove = mYDown;
        break;
      case MotionEvent.ACTION_MOVE:
        mYMove = ev.getRawY();
        float diff = Math.abs(mYMove - mYDown);
        mYLastMove = mYMove;
        // 当手指拖动值大于TouchSlop值时,认为应该进行滚动,拦截子控件的事件
        if (diff > mTouchSlop) {
          return true;
        }
        break;
    }
    return super.onInterceptTouchEvent(ev);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    //▲▲▲2.向VelocityTracker添加MotionEvent
    acquireVelocityTracker(event);
    switch (event.getAction()) {
      case MotionEvent.ACTION_MOVE:

        //▲▲▲3.求伪瞬时速度
        mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
        velocityY = mVelocityTracker.getYVelocity(mPointerId);

        mYMove = event.getRawY();
        int scrolledY = (int) (mYLastMove - mYMove);//注意取的是负值,因为是整个布局在动,而不是控件在动

        if (getScrollY() + scrolledY < topBorder) {// 如果已经在最上端了,就不让再往上滑动了(重点一、边界判断,直接照着这个模板抄就行)
          scrollTo(0, topBorder);
          return true;//★★★★★★★★★★★★★★★★这里返回true或者false实践证明都可以,但是不能什么都不返回。
        } else if (getScrollY() + getHeight() + scrolledY > bottomBorder) {//如果已经在最底部了,就不让再往底部滑动了
          scrollTo(0, bottomBorder - getHeight());
          return true;//★★★★★★★★★★★★★★★★★这里返回true或者false实践证明都可以,但是不能什么都不返回。
        }

        scrollBy(0, scrolledY);//手指move时,布局跟着滚动
        if (mYDown <= mYMove) {//★★★判断手指向上滑动,还是向下滑动,要用mYDown,而不是mYLastMove
          shouZhiXiangXiaHuaDong = true;//手指往下滑动
        } else {
          shouZhiXiangXiaHuaDong = false;//手指往上滑动
        }
        mYLastMove = mYMove;
        break;
      case MotionEvent.ACTION_UP:
//        4.▲▲▲释放VelocityTracker
        releaseVelocityTracker();

        // 第二步,当手指抬起时,根据当前的滚动值以及滚动方向来判定应该滚动到哪个子控件的界面,并且记得调用invalidate();
        if (Math.abs(velocityY) > criticalVelocityY) {//当手指滑动速度快时,按照速度方向直接翻页
//          重点二、快速滑动时,如何判断当前显示的是第几个控件,并且再次包含边界判断(必须包含边界判断,因为前面的边界判断,只适用于低速滑动时)
          if (shouZhiXiangXiaHuaDong) {
            if (currentPage > 1) {//★★★★★★★★边界限制,防止滑倒第一个,还继续滑动,注意★(currentPage-2)
              mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 2) - getScrollY());
              currentPage--;
            }
          } else {
            if (currentPage < childCount) {//★★★★★★★边界限制,防止滑倒最后一个,还继续滑动,注意★currentPage
              mScroller.startScroll(0, getScrollY(), 0, childHeight * currentPage - getScrollY());
              currentPage++;
            }
          }
          Log.e("eee", currentPage + "");
        } else {//当手指滑动速度不够快时,按照松手时,已经滑动的位置来决定翻页

//       重点三、低速滑动时,如何根据位置来判断当前显示的是第几个控件,(这里不必再次进行边界判断,因为第一次的边界判断,在这里会起到作用)
          if ((getScrollY() >= childHeight * (currentPage - 1) + childHeight / 2 && !shouZhiXiangXiaHuaDong)) {
//           手指向上滑动并且,滚动距离过了屏幕一半的距离
            mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage) - getScrollY());
            currentPage++;

          } else if ((getScrollY() < childHeight * (currentPage - 1) + childHeight / 2 && !shouZhiXiangXiaHuaDong)) {
//           手指向上滑动并且,滚动距离没有过屏幕一半的距离
            mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 1) - getScrollY());

          } else if
              ((getScrollY() <= childHeight * (currentPage - 2) + childHeight / 2
                  && shouZhiXiangXiaHuaDong)) {
//            手指向下滑动并且,滚动距离过了屏幕一半的距离
            mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 2) - getScrollY());
            currentPage--;
          } else if
              ((getScrollY() > childHeight * (currentPage - 2) + childHeight / 2
                  && shouZhiXiangXiaHuaDong)) {
//            手指向下滑动并且,滚动距离没有过屏幕一半的距离
            mScroller.startScroll(0, getScrollY(), 0, childHeight * (currentPage - 1) - getScrollY());
          }

          /* if ((getScrollY() >= childHeight && !shouZhiXiangXiaHuaDong)//手指往左滑动,并且滑动完全显示第二个控件时,viewgroup滑动到最右端
              || ((getScrollY() >= (totalChildHeight - firstChildHeight - lastChildHeight) && shouZhiXiangXiaHuaDong))) {//手指往右滑动,并且当滑动没有完全隐藏最后一个控件时,viewgroup滑动到最右端
//          当滚动值大于某个数字时(大于第二个控件的宽度,即完全显示第二个控件时)并且是向左滑动,让这个viewgroup滑动到整个Viewgroup的最右侧,
//          因为右侧的所有控件宽度是600,而现在已经滑动的距离是getScrollX,
//          那么,还应该继续滑动的距离是600-getScrollX(),这里正值表示向右滑动
            mScroller.startScroll(0,getScrollY(), 0, (totalChildHeight - firstChildHeight) - getScrollY());
          } else if ((getScrollY() <= (totalChildHeight - firstChildHeight - lastChildHeight) && shouZhiXiangXiaHuaDong)//手指往右滑动,并且当滑动完全隐藏最后一个控件时,viewgroup滑动到最左端
              || (getScrollY() <= childHeight && !shouZhiXiangXiaHuaDong)) {//手指往左滑动,并且滑动没有完全显示第二个控件时,viewgroup滑动到最左端

//          当滚动值小于某个数字时,让这个viewgroup滑动到整个Viewgroup的最左侧,
//          因为滑动到最左侧时,就是让整个viewgroup的滑动量为0,而现在已经滑动的距离是getScrollX,
//          那么,还应该继续滑动的距离是0-getScrollX(),这里负值表示向左滑动
            mScroller.startScroll(0,getScrollY(), 0, 0 - getScrollY());
          }*/
        }
//        必须调用invalidate()重绘
        invalidate();
        break;

      case MotionEvent.ACTION_CANCEL:
//       5.▲▲▲释放VelocityTracker
        releaseVelocityTracker();

        break;
    }
    return super.onTouchEvent(event);
  }

  @Override
  public void computeScroll() {
    // 第三步,重写computeScroll()方法,并在其内部完成平滑滚动的逻辑
    if (mScroller.computeScrollOffset()) {
      scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
      invalidate();
    }
  }

  /**
   * @param event 向VelocityTracker添加MotionEvent
   * @see VelocityTracker#obtain()
   * @see VelocityTracker#addMovement(MotionEvent)
   */
  private void acquireVelocityTracker(final MotionEvent event) {
    if (null == mVelocityTracker) {
      mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(event);
  }

  /**
   * 释放VelocityTracker
   *
   * @see VelocityTracker#clear()
   * @see VelocityTracker#recycle()
   */
  private void releaseVelocityTracker() {
    if (null != mVelocityTracker) {
      mVelocityTracker.clear();
      mVelocityTracker.recycle();
      mVelocityTracker = null;
    }
  }

   /*  getScrollX()指的是由viewgroup调用View的scrollTo(int x, int y)或者scrollBy(int x, int y)产生的X轴的距离
//        换句话说,就是你手指每次滑动,引起的是viewgroup累计滑动的距离,右为正
//        指的是相当于控件的左上角的为原点的坐标值
        Log.e("qqq","getX():"+event.getX());
//        指的是相当于屏幕的左上角的为原点的坐标值
        Log.e("qqq","getRawX():"+event.getRawX());*/
}

布局文件

 <beautlful.time.com.beautlfultime.view.VerticalViewPager
      android:id="@+id/verticalViewPager"
      android:layout_width="match_parent"
      android:layout_height="150dp">
      <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
      android:background="@android:color/holo_orange_dark"
        android:text="聊天具体的信息哟" />

      <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
        android:text="置顶" />

      <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        android:text="删除" />
      <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
        android:text="美好" />

    </beautlful.time.com.beautlfultime.view.VerticalViewPager>

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android解决viewpager嵌套滑动冲突并保留侧滑菜单功能

    重写子pagerview的dispatchTouchEvent方法,在返回前添加一句getParent().requestDisallowInterceptTouchEvent(true)中断掉事件的传递,类如下 public class SupperViewPager extends ViewPager { private int screenWidth;//屏幕宽度 public SupperViewPager(Context context) { super(context); } pub

  • Android ViewPager撤消左右滑动切换功能实现代码

    最近做项目要求某种情况下ViewPager不能滑动,那么我们只需要重写这个方法就可以禁止ViewPager滑动.下面通过本文给大家ViewPager取消左右滑动切换功能的实例代码,具体代码如下所示: IndexViewPager.Java: <span style="background-color: rgb(255, 255, 255);">import android.content.Context; import android.support.v4.view.Vie

  • Android中TabLayout+ViewPager实现tab和页面联动效果

    TabLayout+ViewPager实现tab和页面联动效果 xml中: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" an

  • Android 中ViewPager重排序与更新实例详解

    Android 中ViewPager重排序与更新实例详解 最近的项目中有栏目订阅功能,在更改栏目顺序以后需要更新ViewPager.类似于网易新闻的频道管理. 在重新排序之后调用了PagerAdapter的notifyDataSetChanged方法,发现ViewPager并没有更新,于是我开始跟踪源码,在调用PagerAdapter的notifyDataSetChanged方法后,会触发Viewpager的dataSetChanged方法. void dataSetChanged() { //

  • Android中DrawerLayout+ViewPager滑动冲突的解决方法

    DrawerLayout 是 Android 官方的侧滑菜单控件,而 ViewPager 相信大家都很熟悉了.今天这里就讲一下当在 DrawerLayout 中嵌套 ViewPager 时,要如何解决滑动冲突的问题,效果如下: 首先,让我们先来解决 DrawerLayout 和 ViewPager 的侧滑事件冲突.当 DrawerLayout 中嵌套 ViewPager 时,侧滑默认是执行 DrawerLayout 的侧滑事件,因为 Android 的事件分发是从 外层 ViewGroup 向里

  • android 中viewpager+fragment仿微信底部TAG完美渐变

    viewpager+fragment仿微信底部TAG完美渐变,在图片渐变的同时字的颜色也在变,注意,是渐变哦! 效果图: activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:zhy="http://schemas.android.com/apk/res/com.Sing.weixin" xmlns:tools="

  • Android使用TabLayou+fragment+viewpager实现滑动切换页面效果

    TabLayou 主要实现的是标题头的 滑动 这个 控件 类似于 ScrollView XML中的布局 <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <android.support.design.widget.TabLayout a

  • Android之禁止ViewPager滑动实现实例

    Android之禁止ViewPager滑动实现实例 当我们想在同一个Activity或者Fragment中展示多个页面时往往会用到ViewPager,通过滑动,我们可以很方便地在不同的页面中切换.但是在某些情况下我们可能并不需要通过滑动来切换ViewPager中的页面(比如为了避免跟页面内的某些触摸事件冲突),而是希望只点击下面或者上面的按钮来切换页面.像知乎那样: 那么有什么方法可以实现不滑动ViewPager呢?其实很简单,只需要自定义一个不滑动的ViewPager就可以了.ViewPage

  • Android 自定义布局竖向的ViewPager的实现

    Android 自定义布局竖向的ViewPager的实现 效果图: 这个自定义控件涉及到的知识点: 自定义ViewGroup中onMeasure和onLayout的写法 弹性滚动Scroller的用法 速度轨迹追踪器VelocityTracker的用法 如何处理滑动事件冲突 dispatchTouchEvent:(外部拦截)告诉此ScrollLayout的父布局,什么时候该拦截触摸事件,什么时候不该拦截触摸事件 onInterceptTouchEvent:(内部拦截)ScrollLayout告诉

  • Android自定义引导玩转ViewPager的方法详解

    ViewPager简介: ViewPager(android.support.v4.view.ViewPager)是android扩展包v4包中的类,这个类可以让用户左右切换当前的view,实现滑动切换的效果. 注意: ViewPager类直接继承了ViewGroup类,也就是说它和我们经常打交道的LinearLayout一样,都是一个容器,需要在里面添加我们想要显示的内容. ViewPager类需要一个PagerAdapter适配器类给它提供数据,这个和ListView类似. ViewPage

  • Android自定义布局实现仿qq侧滑部分代码

    自定义布局实现仿qq侧滑部分Android代码,供大家参考,具体内容如下 源码DEMO地址:https://github.com/applelili/ImitationQQ 实现说明: 通过自定义布局实现: SlidingLayout继承于 HorizontalScrollView /** * Created by Administrator on 2017/3/29. */ public class SlidingLayout extends HorizontalScrollView{ /**

  • Android自定义View Flyme6的Viewpager指示器

    最新更新的Flyme6整体效果不错,动画效果增加了很多了,看了看flyme6的Viewpager指示器,觉得有点意思,就模仿写了一下,整体效果如下: Gradle JitPack v1.0.2 allprojects { repositories { maven { url 'https://jitpack.io' } } } dependencies { compile 'com.github.Dawish:FlymeTabStrip:v1.0.2' } Attrs <declare-styl

  • Android自定义ViewGroup实现竖向引导界面

    一般进入APP都有欢迎界面,基本都是水平滚动的,今天和大家分享一个垂直滚动的例子. 先来看看效果把: 1.首先是布局文件: <com.example.verticallinearlayout.VerticalLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:i

  • Android自定义ViewPager实例

    本文实例讲述了Android自定义ViewPager的方法.分享给大家供大家参考,具体如下: package com.rong.activity; import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.VelocityTracker; import an

  • Android 自定义View实现任意布局的RadioGroup效果

    前言 RadioGroup是继承LinearLayout,只支持横向或者竖向两种布局.所以在某些情况,比如多行多列布局,RadioGroup就并不适用 . 本篇文章通过继承RelativeLayout实现自定义RadioGroup,实现RadioButton的任意布局.效果图如下: 代码(RelativeRadioGroup) /** * Author : BlackHao * Time : 2018/10/26 10:46 * Description : 自定义 RadioGroup */ p

  • Android自定义listview布局实现上拉加载下拉刷新功能

    listview实现上拉加载以及下拉刷新的方式有很多.下面是我写的一种自定义的布局,复用性也比较的强.首先就是继承的listview的自定义view.   AutoListView.Java: package com.example.mic.testdemo.view; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.os.Bu

  • Android不使用自定义布局情况下实现自定义通知栏图标的方法

    本文实例讲述了Android不使用自定义布局情况下实现自定义通知栏图标的方法.分享给大家供大家参考,具体如下: 自定义通知栏图标?不是很简单么.自定义布局都不在话下! 是的,有xml布局文件当然一切都很简单,如果不给你布局文件用呢? 听我慢慢道来! 首先怎么创建一个通知呢? 1.new 一个 复制代码 代码如下: Notification n = new Notification(android.R.drawable.ic_menu_share, null, System.currentTime

  • Android编程实现Toast自定义布局简单示例

    本文实例讲述了Android编程实现Toast自定义布局的方法.分享给大家供大家参考,具体如下: 不知道各位客官是不是觉得系统的toast的信息很难看呢,默认的但黑色背景,毫无色彩. 那么接下来我就教大家用最简单的方式自定义toast布局吧. 首先加载一个自定义的布局 LayoutInflater inflater = context.getLayoutInflater(); View view=inflater.inflate(R.layout.toast_info, null); 然后找到里

随机推荐