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

1.自定义控件(一)

时间:2015-12-05 17:43:49      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:

自定义控件大概分这三种
1、使用系统控件,实现自定义的效果

2、自己定义一个类继承View ,实现特定的效果

3、自定义属性:给自己的控件,添加自己的属性
4、自己定义一个类继承ViewGroup,实现相应的效果


使用系统控件组合成新的控件
1.优酷菜单
技术分享
布局就是三个RelativeLayout,要先声明做为基准的view对象。
activity_main.xml
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity
  6. //第三个
  7. <RelativeLayout
  8. android:id="@+id/level3"
  9. android:layout_width="280dp"
  10. android:layout_height="140dp"
  11. android:layout_alignParentBottom="true"
  12. android:layout_centerHorizontal="true"
  13. android:background="@drawable/level3" >
  14. <ImageView
  15. android:id="@+id/channel1"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:background="@drawable/channel1"
  19. android:layout_alignParentBottom="true"
  20. android:layout_marginLeft="10dp"
  21. android:layout_marginBottom="10dp"
  22. />
  23. <ImageView
  24. android:id="@+id/channel2"
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:layout_above="@id/channel1"
  28. android:layout_alignLeft="@id/channel1"
  29. android:layout_marginBottom="6dp"
  30. android:layout_marginLeft="20dp"
  31. android:background="@drawable/channel2" />
  32. <ImageView
  33. android:id="@+id/channel3"
  34. android:layout_width="wrap_content"
  35. android:layout_height="wrap_content"
  36. android:layout_above="@id/channel2"
  37. android:layout_alignLeft="@id/channel2"
  38. android:layout_marginBottom="6dp"
  39. android:layout_marginLeft="30dp"
  40. android:background="@drawable/channel3" />
  41. <ImageView
  42. android:id="@+id/channel4"
  43. android:layout_width="wrap_content"
  44. android:layout_height="wrap_content"
  45. android:layout_centerHorizontal="true"
  46. android:layout_marginTop="5dp"
  47. android:background="@drawable/channel4" />

  48. <ImageView
  49. android:id="@+id/channel7"
  50. android:layout_width="wrap_content"
  51. android:layout_height="wrap_content"
  52. android:background="@drawable/channel7"
  53. android:layout_alignParentBottom="true"
  54. android:layout_alignParentRight="true"
  55. android:layout_marginBottom="10dp"
  56. android:layout_marginRight="10dp"
  57. />
  58. <ImageView
  59. android:id="@+id/channel6"
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:layout_above="@id/channel7"
  63. android:layout_alignRight="@id/channel7"
  64. android:layout_marginBottom="6dp"
  65. android:layout_marginRight="20dp"
  66. android:background="@drawable/channel6" />
  67. <ImageView
  68. android:id="@+id/channel5"
  69. android:layout_width="wrap_content"
  70. android:layout_height="wrap_content"
  71. android:layout_above="@id/channel6"
  72. android:layout_alignRight="@id/channel6"
  73. android:layout_marginBottom="6dp"
  74. android:layout_marginRight="30dp"
  75. android:background="@drawable/channel5" />
  76. </RelativeLayout>
  77. </RelativeLayout>
MyUtils
RotateAnim 动画的定义,默认的旋转圆心是从标原点,水平向右为0度,角度按顺时针方向增加。
技术分享
  1. public class MyUtils {
  2. /**
  3. * 让指定的view 执行 旋转离开的动画
  4. * @param view
  5. */
  6. public static void startAnimOut(RelativeLayout view) {
  7. startAnimOut(view, 0);
  8. }
  9. /**
  10. * 让指定view 延时 执行旋转离开的动画,
  11. * @param level3
  12. * @param offset 延时的时间
  13. */
  14. public static void startAnimOut(RelativeLayout view, long offset) {
  15. /*
  16. * 默认圆为 为view的左上角,
  17. * 水平向右 为 0度
  18. * 顺时针旋转度数增加
  19. */
  20. RotateAnimation animation =new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
  21. animation.setDuration(500); // 设置运行的时间
  22. animation.setFillAfter(true); //动画执行完以后,保持最后的状态
  23. animation.setStartOffset(offset); // 设置延时执行的时间
  24. view.startAnimation(animation);
  25. }
  26. /**
  27. * 让指定的view 执行 旋转进入的动画
  28. * @param view
  29. */
  30. public static void startAnimIn(RelativeLayout view) {
  31. startAnimIn(view, 0);
  32. }
  33. /**
  34. * 让指定的view 延时执行 旋转进入的动画
  35. * @param level2
  36. * @param i 延时的时间
  37. */
  38. public static void startAnimIn(RelativeLayout view, int i) {
  39. /*
  40. * 默认圆为 为view的左上角,
  41. * 水平向右 为 0度
  42. * 顺时针旋转度数增加
  43. */
  44. RotateAnimation animation =new RotateAnimation(180, 360, view.getWidth()/2, view.getHeight());
  45. animation.setDuration(500); // 设置运行的时间
  46. animation.setFillAfter(true); //动画执行完以后,保持最后的状态
  47. animation.setStartOffset(i); //设置延时执行的时间
  48. view.startAnimation(animation);
  49. }
  50. }
MainActivity:isLevel3Show = !isLevel3Show是个好方法,当点击按钮时值变化
  1. public class MainActivity extends Activity implements OnClickListener {
  2. private ImageView icon_menu;
  3. private ImageView icon_home;
  4. private RelativeLayout level1;
  5. private RelativeLayout level2;
  6. private RelativeLayout level3;
  7. /**
  8. * 判断 第3级菜单是否显示
  9. * true 为显示
  10. */
  11. private boolean isLevel3Show = true;
  12. /**
  13. * 判断 第2级菜单是否显示
  14. * true 为显示
  15. */
  16. private boolean isLevel2Show = true;
  17. /**
  18. * 判断 第1级菜单是否显示
  19. * true 为显示
  20. */
  21. private boolean isLevel1show = true;
  22. @Override
  23. protected void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.activity_main);
  26. icon_home = (ImageView) findViewById(R.id.icon_home);
  27. icon_menu = (ImageView) findViewById(R.id.icon_menu);
  28. level1 = (RelativeLayout) findViewById(R.id.level1);
  29. level2 = (RelativeLayout) findViewById(R.id.level2);
  30. level3 = (RelativeLayout) findViewById(R.id.level3);
  31. icon_home.setOnClickListener(this);
  32. icon_menu.setOnClickListener(this);
  33. }
  34. @Override
  35. public void onClick(View v) {
  36. switch (v.getId()) {
  37. case R.id.icon_menu: //处理 menu 图标的点击事件
  38. // 如果第3级菜单是显示状态,那么将其隐藏
  39. if(isLevel3Show){
  40. //隐藏 第3级菜单
  41. MyUtils.startAnimOut(level3);
  42. }else{
  43. // 如果第3级菜单是隐藏状态,那么将其显示
  44. MyUtils.startAnimIn(level3);
  45. }
  46. isLevel3Show = !isLevel3Show;
  47. break;
  48. case R.id.icon_home: //处理 home 图标 的点击事件
  49. // 如果第2级菜单是显示状态,那么就隐藏,2,3级菜单
  50. if(isLevel2Show ){
  51. MyUtils.startAnimOut(level2);
  52. isLevel2Show = false;
  53. if(isLevel3Show){ // 如果此时,第3级菜单也显示,那也将其隐藏
  54. MyUtils.startAnimOut(level3,200);
  55. isLevel3Show = false;
  56. }
  57. }else{
  58. // 如果第2级菜单是隐藏状态,那么就显示2级菜单
  59. MyUtils.startAnimIn(level2);
  60. isLevel2Show = true;
  61. }
  62. break;
  63. }
  64. }
  65. /**
  66. * 改变第1级菜单的状态
  67. */
  68. private void changeLevel1State() {
  69. //如果第1级菜单是显示状态,那么就隐藏 1,2,3级菜单
  70. if(isLevel1show){
  71. MyUtils.startAnimOut(level1);
  72. isLevel1show = false;
  73. if(isLevel2Show){ // 判断2级菜单是否显示
  74. MyUtils.startAnimOut(level2,100);
  75. isLevel2Show = false;
  76. if(isLevel3Show){ // 判断3级菜单是否显示
  77. MyUtils.startAnimOut(level3,200);
  78. isLevel3Show = false;
  79. }
  80. }
  81. }else{
  82. //如果第1级菜单是隐藏状态,那么就显示 1,2级菜单
  83. MyUtils.startAnimIn(level1);
  84. isLevel1show = true;
  85. MyUtils.startAnimIn(level2,200);
  86. isLevel2Show = true;
  87. }
  88. }
  89. @Override
  90. /**
  91. * 响应按键的动作
  92. */
  93. public boolean onKeyDown(int keyCode, KeyEvent event) {
  94. if(keyCode == KeyEvent.KEYCODE_MENU){ // 监听 menu 按键
  95. changeLevel1State();
  96. }
  97. return super.onKeyDown(keyCode, event);
  98. }
  99. }
2.ViewPager轮播
MainActivity
#33000000 半透明背景
自动轮播方法重点看看
  1. public class MainActivity extends Activity {
  2. private ViewPager viewPager;
  3. private LinearLayout pointGroup;
  4. private TextView iamgeDesc;
  5. // 图片资源ID
  6. private final int[] imageIds = { R.drawable.a, R.drawable.b, R.drawable.c,
  7. R.drawable.d, R.drawable.e };
  8. //图片标题集合
  9. private final String[] imageDescriptions = {
  10. "巩俐不低俗,我就不能低俗",
  11. "扑树又回来啦!再唱经典老歌引万人大合唱",
  12. "揭秘北京电影如何升级",
  13. "乐视网TV版大派送",
  14. "热血屌丝的反杀"
  15. };
  16. private ArrayList<ImageView> imageList;
  17. /**
  18. * 上一个页面的位置
  19. */
  20. protected int lastPosition;
  21. @Override
  22. protected void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.activity_main);
  25. viewPager = (ViewPager) findViewById(R.id.viewpager);
  26. pointGroup = (LinearLayout) findViewById(R.id.point_group);
  27. iamgeDesc = (TextView) findViewById(R.id.image_desc);
  28. iamgeDesc.setText(imageDescriptions[0]);
  29. imageList = new ArrayList<ImageView>();
  30. for (int i = 0; i <imageIds.length; i++) {
  31. //初始化图片资源
  32. ImageView image = new ImageView(this);
  33. image.setBackgroundResource(imageIds[i]);
  34. imageList.add(image);
  35. //添加指示点
  36. ImageView point =new ImageView(this);
  37. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  38. LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  39. params.rightMargin = 20;
  40. point.setLayoutParams(params);
  41. point.setBackgroundResource(R.drawable.point_bg);
  42. if(i==0){
  43. point.setEnabled(true);
  44. }else{
  45. point.setEnabled(false);
  46. }
  47. pointGroup.addView(point);
  48. }
  49. viewPager.setAdapter(new MyPagerAdapter());
  50. // viewPager.setCurrentItem(Integer.MAX_VALUE/2 - (Integer.MAX_VALUE/2%imageList.size())) ;
  51. viewPager.setOnPageChangeListener(new OnPageChangeListener() {
  52. @Override
  53. /**
  54. * 页面切换后调用
  55. * position 新的页面位置
  56. */
  57. public void onPageSelected(int position) {
  58. position = position%imageList.size();
  59. //设置文字描述内容
  60. iamgeDesc.setText(imageDescriptions[position]);
  61. //改变指示点的状态
  62. //把当前点enbale 为true
  63. pointGroup.getChildAt(position).setEnabled(true);
  64. //把上一个点设为false
  65. pointGroup.getChildAt(lastPosition).setEnabled(false);
  66. lastPosition = position;
  67. }
  68. @Override
  69. /**
  70. * 页面正在滑动的时候,回调
  71. */
  72. public void onPageScrolled(int position, float positionOffset,
  73. int positionOffsetPixels) {
  74. }
  75. @Override
  76. /**
  77. * 当页面状态发生变化的时候,回调
  78. */
  79. public void onPageScrollStateChanged(int state) {
  80. }
  81. });
  82. /*
  83. * 自动循环:
  84. * 1、定时器:Timer
  85. * 2、开子线程 while true 循环
  86. * 3、ColckManager
  87. * 4、 用handler 发送延时信息,实现循环
  88. */
  89. isRunning = true;
  90. // handler.sendEmptyMessageDelayed(0, 2000);
  91. }
  92. /**
  93. * 判断是否自动滚动
  94. */
  95. private boolean isRunning = false;
  96. private Handler handler = new Handler(){
  97. public void handleMessage(android.os.Message msg) {
  98. //让viewPager 滑动到下一页
  99. viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
  100. if(isRunning){
  101. handler.sendEmptyMessageDelayed(0, 2000);
  102. }
  103. };
  104. };
  105. protected void onDestroy() {
  106. isRunning = false;
  107. };
  108. private class MyPagerAdapter extends PagerAdapter {
  109. @Override
  110. /**
  111. * 获得页面的总数
  112. */
  113. public int getCount() {
  114. return Integer.MAX_VALUE;
  115. }
  116. @Override
  117. /**
  118. * 获得相应位置上的view
  119. * container view的容器,其实就是viewpager自身
  120. * position 相应的位置
  121. */
  122. public Object instantiateItem(ViewGroup container, int position) {
  123. System.out.println("instantiateItem ::"+position);
  124. // 给 container 添加一个view
  125. container.addView(imageList.get(position%imageList.size()));
  126. //返回一个和该view相对的object
  127. return imageList.get(position%imageList.size());
  128. }
  129. @Override
  130. /**
  131. * 判断 view和object的对应关系
  132. */
  133. public boolean isViewFromObject(View view, Object object) {
  134. if(view == object){
  135. return true;
  136. }else{
  137. return false;
  138. }
  139. }
  140. @Override
  141. /**
  142. * 销毁对应位置上的object
  143. */
  144. public void destroyItem(ViewGroup container, int position, Object object) {
  145. System.out.println("destroyItem ::"+position);
  146. container.removeView((View) object);
  147. object = null;
  148. }
  149. }
  150. }
3.下拉框效果
技术分享
在editText的右边放置一个小箭头的图片,点击图片,在editText的下方弹出一个popupWindow,并对popupWindow进行一些设置即得到想要的效果。
popupWindow是个listview,重点是popupWindow的用法
MainActivity
  1. public class MainActivity extends Activity {
  2. private EditText input;
  3. private ImageView downArrow;
  4. private List<String> msgList;
  5. private PopupWindow popWin;
  6. private ListView listView;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. input = (EditText) findViewById(R.id.input);
  12. downArrow = (ImageView) findViewById(R.id.down_arrow);
  13. msgList = new ArrayList<String>();
  14. for (int i = 0; i < 20; i++) {
  15. msgList.add("1000000000"+i);
  16. }
  17. initListView();
  18. downArrow.setOnClickListener(new OnClickListener() {
  19. @Override
  20. public void onClick(View v) {
  21. System.out.println("=======");
  22. //定义 popupWindow
  23. popWin = new PopupWindow(MainActivity.this);
  24. popWin.setWidth(input.getWidth()); //设置宽度
  25. popWin.setHeight(200); //设置popWin 高度
  26. popWin.setContentView(listView); //为popWindow填充内容
  27. popWin.setOutsideTouchable(true); // 点击popWin 以处的区域,自动关闭 popWin
  28. popWin.showAsDropDown(input, 0, 0);//设置 弹出窗口,显示的位置
  29. }
  30. });
  31. }
  32. private void initListView() {
  33. listView = new ListView(this);
  34. listView.setBackgroundResource(R.drawable.listview_background); //设置listView 背景
  35. listView.setDivider(null); //设置条目之间的分隔线为null
  36. listView.setVerticalScrollBarEnabled(false); // 关闭
  37. listView.setAdapter(new MyListAdapter());
  38. }
  39. private class MyListAdapter extends BaseAdapter{
  40. @Override
  41. public int getCount() {
  42. return msgList.size();
  43. }
  44. @Override
  45. public Object getItem(int position) {
  46. return position;
  47. }
  48. @Override
  49. public long getItemId(int position) {
  50. return position;
  51. }
  52. @Override
  53. public View getView(final int position, View convertView, ViewGroup parent) {
  54. ViewHolder holder;
  55. if(convertView == null){
  56. convertView = View.inflate(getApplicationContext(), R.layout.list_item, null);
  57. holder = new ViewHolder();
  58. holder.delete = (ImageView) convertView.findViewById(R.id.delete);
  59. holder.tv_msg =(TextView) convertView.findViewById(R.id.tv_list_item);
  60. convertView.setTag(holder);
  61. }else{
  62. holder = (ViewHolder) convertView.getTag();
  63. }
  64. holder.tv_msg.setText(msgList.get(position));
  65. holder.delete.setOnClickListener(new OnClickListener() {
  66. @Override
  67. public void onClick(View v) {
  68. //删除对应的条目
  69. msgList.remove(position);
  70. //刷新listView
  71. MyListAdapter.this.notifyDataSetChanged();
  72. }
  73. });
  74. convertView.setOnClickListener(new OnClickListener() {
  75. @Override
  76. public void onClick(View v) {
  77. //设置输入框
  78. input.setText(msgList.get(position));
  79. popWin.dismiss();
  80. }
  81. });
  82. return convertView;
  83. }
  84. }
  85. private class ViewHolder{
  86. TextView tv_msg;
  87. ImageView delete;
  88. }
  89. }






1.自定义控件(一)

标签:

原文地址:http://www.cnblogs.com/liuyu0529/p/5021875.html

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