参考文章: http://blog.csdn.net/guolin_blog/article/details/12921889
Android LayoutInflater原理分析,带你一步步深入了解View(一)
Android自定义View的实现方法,带你一步步深入了解View(四)

这里面总共有三种自定义控件:

自绘控件、组合控件、继承控件

 

  1. 自绘控件
    1. package com.example.DefineView1;
    2.  
    3. import android.content.Context;
    4. import android.graphics.Canvas;
    5. import android.graphics.Color;
    6. import android.graphics.Paint;
    7. import android.graphics.Rect;
    8. import android.util.AttributeSet;
    9. import android.view.View;
    10.  
    11. /**
    12.  * Created by zhuxuekui on 2015/5/18.
    13.  */
    14.  
    15. /**
    16.  * 自定义组合控件之 自绘控件
    17.  */
    18. public
      class CounterView extends View implements View.OnClickListener {
    19.  
    20.     private Paint mPaint;
    21.     private Rect mBounds;
    22.     private
      int mCount;
    23.     public CounterView(Context context, AttributeSet attrs) {
    24.         super(context, attrs);
    25.         mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    26.         mBounds = new Rect();
    27.         setOnClickListener(this);
    28.  
    29.     }
    30.  
    31.     @Override
    32.     protected
      void onDraw(Canvas canvas) {
    33.         super.onDraw(canvas);
    34.         mPaint.setColor(Color.BLUE);
    35.         canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
    36.         mPaint.setColor(Color.YELLOW);
    37.         mPaint.setTextSize(30);
    38.         String text = String.valueOf(mCount);
    39.         mPaint.getTextBounds(text,0,text.length(),mBounds);// 获取文字区域(其实是一个mBounds)的宽度与高度,然后回调。
    40.         float textWidth = mBounds.width();
    41.         float textHeight = mBounds.height();
    42.         canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2
    43.                 + textHeight / 2, mPaint); //在画布上绘制文字
    44.     }
    45.  
    46.     @Override
    47.     public
      void onClick(View view) {
    48.           mCount++;
    49.           invalidate(); //重绘
    50.     }
    51. }

    在CounterView中,我们先初始化一些数据,然后设置view的点击事件。然后调用onclick方法,这里面有invalidate方法,重绘命令。然后调用ondraw方法,开始进行视图的绘制。

     

    1. package com.example.DefineView1;
    2.  
    3. import android.app.Activity;
    4. import android.os.Bundle;
    5.  
    6. public
      class MyActivity extends Activity {
    7.     /**
    8.      * Called when the activity is first created.
    9.      */
    10.     @Override
    11.     public
      void onCreate(Bundle savedInstanceState) {
    12.         super.onCreate(savedInstanceState);
    13.         setContentView(R.layout.main);
    14.     }
    15. }

 

 

  1. 组合控件

程序结构:

  1. package com.example.DefineView2;
  2.  
  3. import android.app.Activity;
  4. import android.content.Context;
  5. import android.util.AttributeSet;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.FrameLayout;
  10. import android.widget.TextView;
  11.  
  12. /**
  13.  * Created by zhuxuekui on 2015/5/18.
  14.  */
  15. public
    class TitleView extends FrameLayout {
  16.  
  17.     private Button leftButton;
  18.     private TextView titleText;
  19.     public TitleView(Context context, AttributeSet attrs) {
  20.         super(context, attrs);
  21.         LayoutInflater.from(context).inflate(R.layout.title, this);
  22.         titleText = (TextView)findViewById(R.id.title_text);
  23.         leftButton = (Button)findViewById(R.id.button_left);
  24.         leftButton.setOnClickListener(new OnClickListener() {
  25.             @Override
  26.             public
    void onClick(View view) {
  27.                 ((Activity)getContext()).finish();
  28.             }
  29.         });
  30.     }
  31.  
  32.     public
    void setTitleText(String text)
  33.     {
  34.         titleText.setText(text);
  35.     }
  36.  
  37.     public
    void setLeftButtonText(String text)
  38.     {
  39.         leftButton.setText(text);
  40.     }
  41.  
  42.     public
    void setLeftButtonListener(OnClickListener l)
  43.     {
  44.         leftButton.setOnClickListener(l);
  45.     }
  46. }

首先我们定义title.xml下面的,然后定义TextView 继承FragmentLayout ,代码如上面的所示。里面我们对xml里面的控件进行初始化,设置事件都可以。

 

 

 

 

  1. 继承控件

    截图:

    程序结构:

     

     

    1)增加的小按钮,只有一个button,没有布局

    Delete_button.xml 子定义的listview里面增加的内容

     

    2)编写我们自己的mylistview类

    Mylistview

    1. package com.example.DefineView3;
    2.  
    3. import android.content.Context;
    4. import android.util.AttributeSet;
    5. import android.view.*;
    6. import android.widget.ListView;
    7. import android.widget.RelativeLayout;
    8.  
    9. /**
    10.  * Created by zhuxuekui on 2015/5/18.
    11.  */
    12. public
      class MyListView extends ListView implements View.OnTouchListener,GestureDetector.OnGestureListener {
    13.     private GestureDetector gestureDetector;
    14.     private OnDeleteListener listener;
    15.     private View deleteButton;
    16.     private ViewGroup itemLayout;
    17.     private
      int selectedItem;
    18.     private
      boolean isDeleteShown;
    19.  
    20.     public MyListView(Context context, AttributeSet attrs) {
    21.         super(context, attrs);
    22.         gestureDetector = new GestureDetector(getContext(),this);
    23.         setOnTouchListener(this);
    24.     }
    25.  
    26.     public
      void setOnDeleteListener(OnDeleteListener l)
    27.     {
    28.         listener = l;
    29.     }
    30.  
    31.  
    32.  
    33.  
    34.     @Override
    35.     public
      boolean onTouch(View view, MotionEvent motionEvent) {
    36.         if(isDeleteShown){
    37.             itemLayout.removeView(deleteButton);
    38.             deleteButton = null;
    39.             isDeleteShown = false;
    40.             return
      false;
    41.         }else{
    42.             return gestureDetector.onTouchEvent(motionEvent);
    43.         }
    44.     }
    45.  
    46. //下面几个方法是OnTouchEvent的事件处理
    47.  
    48.     /**
    49.      * 手指按下事件处理
    50.      * @param motionEvent
    51.      * @return
    52.      */
    53.     @Override
    54.     public
      boolean onDown(MotionEvent motionEvent) {
    55.         if(!isDeleteShown)
    56.         {
    57.             selectedItem = pointToPosition((int)motionEvent.getX(),(int)motionEvent.getY());//判断当前选中的是listview的第几行
    58.         }
    59.         return
      false;
    60.     }
    61.  
    62.     /**
    63.      * 快速滑动事件处理
    64.      * @param motionEvent
    65.      * @param motionEvent1
    66.      * @param X
    67.      * @param Y
    68.      * @return
    69.      */
    70.     @Override
    71.     public
      boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float X, float Y) {
    72.  
    73.         // 快速滑动到某一行上,加载布局deleteButton,并将删除按钮添加到当前选中的那一行item中
    74.         if(!isDeleteShown && Math.abs(X) > Math.abs(Y)){
    75.             deleteButton = LayoutInflater.from(getContext()).inflate(R.layout.delete_button,null);
    76.             deleteButton.setOnClickListener(new OnClickListener() {
    77.                 @Override
    78.                 public
      void onClick(View view) {
    79.                     //当点击了删除按钮,我们就去回调onDeleteListener的onDelete()方法
    80.                     itemLayout.removeView(deleteButton);
    81.                     deleteButton = null;
    82.                     isDeleteShown = false;
    83.                     listener.onDelete(selectedItem);
    84.                 }
    85.             });
    86.  
    87.             itemLayout = (ViewGroup)getChildAt(selectedItem - getFirstVisiblePosition());
    88.             RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
    89.             params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    90.             params.addRule(RelativeLayout.CENTER_VERTICAL);
    91.             itemLayout.addView(deleteButton, params);
    92.             isDeleteShown = true;
    93.         }
    94.  
    95.         return
      false;
    96.     }
    97.  
    98.     @Override
    99.     public
      void onShowPress(MotionEvent motionEvent) {
    100.  
    101.     }
    102.  
    103.     @Override
    104.     public
      boolean onSingleTapUp(MotionEvent motionEvent) {
    105.         return
      false;
    106.     }
    107.  
    108.     @Override
    109.     public
      boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
    110.         return
      false;
    111.     }
    112.  
    113.     @Override
    114.     public
      void onLongPress(MotionEvent motionEvent) {
    115.  
    116.     }
    117.  
    118.     public
      interface OnDeleteListener{
    119.         void onDelete(int index);
    120.     }
    121. }

    先去执行构造方法,创建gestureDetector手势捕捉监听程序,以及注册了ontouch监听。当我们按下的时候,触屏就算,程序执行到onTouch() 中,如果删除按钮已经显示我们删除掉图标,如果没有显示删除图标,我们使用gestureDetector来处理当前手势。然后我们执行gestureDetector.onTouchEvent(motionEvent) 。这里面包含多个方法,首先是onDown(),捕捉我们的手指按在了哪一行,我们记录下,滑动的时候,执行onfling(),

    当按钮没有显示,然后我们去加载delete_button.xml此布局,然后并将其现在在listview当前选择的那一行上面,当我们点击删除图标的时候,执行回调方法,执行相应的逻辑。这部分逻辑在主界面中完成。

     

     

    3)建立listview里面的子项

    至此,新建上面的mylistview里面的每一个子项,my_list_view_item.xml.

    My_list_view_item.xml listview 的子项

     

     

    4)建立适配器类,继承ArrayAdapter

     

    下一步就是新建适配器类

    1. package com.example.DefineView3;
    2.  
    3. import android.content.Context;
    4. import android.view.LayoutInflater;
    5. import android.view.View;
    6. import android.view.ViewGroup;
    7. import android.widget.ArrayAdapter;
    8. import android.widget.TextView;
    9.  
    10. import java.util.List;
    11.  
    12. /**
    13.  * Created by zhuxuekui on 2015/5/18.
    14.  */
    15. public
      class MyAdapter extends ArrayAdapter<String> {
    16.  
    17.     public MyAdapter(Context context, int resource, List<String> objects) {
    18.         super(context, resource, objects);
    19.     }
    20.  
    21.     @Override
    22.     public View getView(int position, View convertView, ViewGroup parent) {
    23.         View view;
    24.         if(convertView == null)
    25.         {
    26.             view = LayoutInflater.from(getContext()).inflate(R.layout.my_list_view_item,null);
    27.         }else{
    28.             view = convertView;
    29.         }
    30.  
    31.         TextView textView = (TextView)view.findViewById(R.id.text_view);
    32.         textView.setText(getItem(position));
    33.         return view;
    34.     }
    35. }

    这一步主要就是重载ArrayAdapter,并重写构造方法和getview方法。

     

    5)编写主界面的布局,使用自定义的listview控件

     

    Mail.xml 布局自定义的listview

     

     

    6)写主界面myactivity.java

    1. package com.example.DefineView3;
    2.  
    3. import android.app.Activity;
    4. import android.os.Bundle;
    5.  
    6. import java.util.ArrayList;
    7. import java.util.List;
    8.  
    9.  
    10. /**
    11.  * 自定义控件3 之 继承控件
    12.  */
    13. public
      class MyActivity extends Activity {
    14.  
    15.     private MyListView myListView;
    16.     private MyAdapter adapter;
    17.     private List<String> contentList = new ArrayList<String>();
    18.  
    19.     /**
    20.      * Called when the activity is first created.
    21.      */
    22.     @Override
    23.     public
      void onCreate(Bundle savedInstanceState) {
    24.         super.onCreate(savedInstanceState);
    25.         setContentView(R.layout.main);
    26.         initList();
    27.         myListView = (MyListView)findViewById(R.id.my_list_view);
    28.         myListView.setOnDeleteListener(new MyListView.OnDeleteListener() {
    29.             @Override
    30.             public
      void onDelete(int index) {
    31.                 contentList.remove(index);
    32.                 adapter.notifyDataSetChanged();
    33.             }
    34.         });
    35.  
    36.         adapter = new MyAdapter(this,0,contentList);
    37.         myListView.setAdapter(adapter);
    38.     }
    39.  
    40.     private
      void initList(){
    41.         contentList.add("Content Item 1");
    42.         contentList.add("Content Item 2");
    43.         contentList.add("Content Item 3");
    44.         contentList.add("Content Item 4");
    45.         contentList.add("Content Item 5");
    46.         contentList.add("Content Item 6");
    47.         contentList.add("Content Item 7");
    48.         contentList.add("Content Item 8");
    49.         contentList.add("Content Item 9");
    50.         contentList.add("Content Item 10");
    51.         contentList.add("Content Item 11");
    52.         contentList.add("Content Item 12");
    53.         contentList.add("Content Item 13");
    54.         contentList.add("Content Item 14");
    55.         contentList.add("Content Item 15");
    56.         contentList.add("Content Item 16");
    57.         contentList.add("Content Item 17");
    58.         contentList.add("Content Item 18");
    59.         contentList.add("Content Item 19");
    60.         contentList.add("Content Item 20");
    61.     }
    62. }

深入了解view以及自定义控件的更多相关文章

  1. view之自定义控件

    转载自:http://blog.163.com/ppy2790@126/blog/static/103242241201382210910473/ 开发自定义控件的步骤: 1.了解View的工作原理  ...

  2. 安卓自定义控件(三)实现自定义View

    前面两篇博客,把View绘制的方法说了一下,但是,我们只在onDraw里面做文章,控件都是直接传入一个Context,还不能在布局文件里使用自定义View.这一篇博客,就不再讲绘制,在我们原先的基础上 ...

  3. Android自定义控件View(一)

    虽然Android API给我们提供了众多控件View来使用,但是鉴于Android的开发性,自然少不了根据需求自定义控件View了.比如说QQ头像是圆形的,但是纵观整个Android控件也找不到一个 ...

  4. android自定义控件一站式入门

    自定义控件 Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理. 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自View的类,这包括展示最终内容的非 ...

  5. Android之自定义View的实现

    对于学习Android开发的小童鞋对于自定义View一定不会陌生,相信大家对它是又爱又恨,爱它可以跟随我们的心意设计出漂亮的效果:恨它想要完全流畅掌握,需要一定的功夫.对于初学者来说确实很不容易,网上 ...

  6. Andriod 自定义控件之音频条

    今天我们实现一个直接继承于View的全新控件.大家都知道音乐播放器吧,在点击一首歌进行播放时,通常会有一块区域用于显示音频条,我们今天就来学习下,播放器音频条的实现. 首先我们还是先定义一个类,直接继 ...

  7. Android自定义控件

    开发自定义控件的步骤: 1.了解View的工作原理  2. 编写继承自View的子类 3. 为自定义View类增加属性  4. 绘制控件  5. 响应用户消息  6 .自定义回调函数    一.Vie ...

  8. Android 自定义View 三板斧之三——重写View来实现全新控件

    通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 本文来讨论最难的一种 ...

  9. Android 自定义控件(一)

    本文用一个简单的例子来说明一下自定义控件的步骤实现,自定义控件有几种实现类型,分别为继承自view完全自定义,继承现有的 控件实现特定效果,继承viewgroup实现布局类等: 本文研究的是继承自vi ...

随机推荐

  1. 【读书笔记】iOS-安全地传输用户密码的方法

    正确做法:事先生成一对用于加密的公私钥,客户端在登录时,使用公钥将用户的密码加密后,将密文传输到服务器.服务器使用私钥将密码解密,然后加盐之后多次请求MD5,之后再和服务器原来存储的用同样方法处理过的 ...

  2. iOS开发之网络编程--1、AFNetwork 3.x 的所有开发中常用基础介绍

    前言:第三方网络请求框架中AFNetwork 3.x收欢迎程度相当高的: 由于iOS 7 和 Mac OS X 10.9 Mavericks 中一个显著的变化就是对 Foundation URL 加载 ...

  3. IOS开发--常用工具类收集整理(Objective-C)(持续更新)

    前言:整理和收集了IOS项目开发常用的工具类,最后也给出了源码下载链接. 这些可复用的工具,一定会给你实际项目开发工作锦上添花,会给你带来大大的工作效率. 重复造轮子的事情,除却自我多练习编码之外,就 ...

  4. UVa 101 - The Blocks Problem(积木问题,指令操作)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  5. 剔除editor编辑器中的HTML标签

    1.剔除editor编辑器中的HTML标签 public static string striphtml(string strhtml)    {        string stroutput = ...

  6. 正确使用 Volatile 变量——Brian Goetz

    本文转自:http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 由Java并发大师Brian Goetz所撰写的. Java 语言中的 v ...

  7. 关于移动端的font和图片的问题

    一.font-family 使用无衬线字体 body { font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif ...

  8. cocos2d-x之Vector与map

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  9. [转]How to insert a row between two rows in an existing excel with HSSF (Apache POI)

    本文转自:http://stackoverflow.com/questions/5785724/how-to-insert-a-row-between-two-rows-in-an-existing- ...

  10. List与Set的使用

    接口Collection: Collection是Java的一个集合框架, 也是一个根接口.JDK中没有提供此接口的任何实现,但是提供了更具体的子接口Set和List接口的实现,所有的Collecti ...