码迷,mamicode.com
首页 > 其他好文 > 详细

深入了解view以及自定义控件

时间:2015-05-19 00:45:54      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:

参考文章: 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以及自定义控件

标签:

原文地址:http://www.cnblogs.com/zhuxuekui/p/4513427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!