Android学习——自定义控件(1)

来源:互联网 发布:手机上开淘宝店怎么开 编辑:程序博客网 时间:2024/06/08 12:14

自定义控件的学习,涉及的东西比较多。第一次发博客,先学习一下别人SwipeListView控件。

项目描述:

   这个项目做的是一个扩展性的listview,其中的item可以左滑,可以将置顶和删除的功能按钮显示出来。

项目github地址:

   https://github.com/yuqirong/SwipeListView

代码解析:

   1、项目中只有一个activity类——MainActivity.java,另一个是自定义控件类——SwipeListLayout.java。 activity中只有一个普通的listview,其中listview的item才是真正的核心内容,涉及到滑动事件的处理。不过目前有点问题,在横向滑动容易误操作,导致左滑失败。后续优化一下。

   2、activity类解析

   initList(); 

              ——初始化listview显示的内容,一个list承载多个字符串

   lv_main.setAdapter(new ListAdapter());

              ——设置listview的适配器

  class ListAdapter extends BaseAdapter {

        @Override

      public int getCount() { return list.size(); }

      @Override

      public Object getItem(int arg0) { return list.get(arg0); }

      @Override

      public long getItemId(int arg0) { return arg0; }

      @Override

      public View getView(final int arg0, View view, ViewGroup arg2)

         { if (view == null) {

              view = LayoutInflater.from(MainActivity.this).inflate( R.layout.slip_list_item, null);

          }

          TextView tv_name = (TextView) view.findViewById(R.id.tv_name);

          tv_name.setText(list.get(arg0));

          final SwipeListLayout sll_main = (SwipeListLayout) view .findViewById(R.id.sll_main);

          TextView tv_top = (TextView) view.findViewById(R.id.tv_top);

          TextView tv_delete = (TextView) view.findViewById(R.id.tv_delete);

          sll_main.setOnSwipeStatusListener(new MyOnSlipStatusListener( sll_main));

          tv_top.setOnClickListener(new OnClickListener() {

              @Override

              public void onClick(View view) {

                  sll_main.setStatus(SwipeListLayout.Status.Close, true);

                  String str = list.get(arg0);

                  list.remove(arg0);

                  list.add(0, str);

                  notifyDataSetChanged();

              }

          });

          tv_delete.setOnClickListener(new OnClickListener() {

              @Override

              public void onClick(View view) {

                  sll_main.setStatus(SwipeListLayout.Status.Close, true);

                  list.remove(arg0);

                  notifyDataSetChanged();

              }

          });

          return view;

      }

  }

   ListAdapter继承了BaseAdapter,重点看一下getView。先找到item的布局,这个布局中包含了显示的内容,还有置顶和删除的按钮。现在先将内容设置好,然后将自定义布局设置setOnSwipeStatusListener,这是一个自定义布局的状态监听器,用来监听自定义布局触摸状态。后面设置置顶按钮,设置删除按钮。


3、SwipeListLayout类解析

       public void setStatus(Status status, boolean smooth) {

            this.status = status;

            if (status == Status.Open) {

                 open(smooth); } else { close(smooth);

            }

        }

        设置item的状态,以便于后续对item的行为进行设置。

        public void setOnSwipeStatusListener(OnSwipeStatusListener listener) {

              this.listener = listener;

        }

        设置item的状态监听事件

        public interface OnSwipeStatusListener {

              /**

               *当状态改变时回调

               *

              * @param status

               */

              void onStatusChanged(Status status);

              /**

               *开始执行Close动画

               */

              void onStartCloseAnimation();

              /**

               *开始执行Open动画

               */

              void onStartOpenAnimation();

          }

          public SwipeListLayout(Context context, AttributeSet attrs) {

                super(context, attrs);

                mDragHelper = ViewDragHelper.create(this, callback);

          }

          // ViewDragHelper的回调

          Callback callback = new Callback() {

                @Override

                public boolean tryCaptureView(View view, int arg1) {

                      return view == itemView;

                }

                @Override

                public int clampViewPositionHorizontal(View child, int left, int dx) {

                      if (child == itemView) {

                             if (left > 0) {

                                    return 0;

                             } else {

                                   left = Math.max(left, -hiddenViewWidth);

                                   return left;

                             }

                       }

                       return 0;

                 }

                 @Override

                 public int getViewHorizontalDragRange(View child) {

                       return hiddenViewWidth;

                 }

                 @Override

                 public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {

                      if (itemView == changedView) {

                      hiddenView.offsetLeftAndRight(dx);

                 }

                 // 有时候滑动很快的话 会出现隐藏按钮的linearlayout没有绘制的问题

                 // 为了确保绘制成功 调用 invalidate invalidate();

            }

            public void onViewReleased(View releasedChild, float xvel, float yvel) {

                 // 向右滑xvel为正 向左滑xvel为负

                 if (releasedChild == itemView) {

                       if (xvel == 0 && Math.abs(itemView.getLeft()) > hiddenViewWidth / 2.0f) {

                             open(smooth);

                       } else if (xvel < 0) {

                             open(smooth);

                       } else {

                             close(smooth);

                       }

                 }

             }

        };

       上面这段代码和ViewDragHelper相关,重点介绍一下。

阅读全文
0 0