实例讲解Android应用中自定义组合控件的方法_Android

自定义view大概可以分成:

  • 继承view
  • 组合view
  • 自己画的view(用paint和canvas)
  • 自定义viewgroup(widget)

最近又跟同学聊起来了,于是就准备自己实现一个imagebutton来练练手。(最简单的了)以及后面一个把imageview与textview结合使用的案例。

ImageButton
要实现ImageButton最容易想到的不就是把button和imageview合在一起么。嗯,人容易就想到这是一个组合自定义view。可是如何把一个image放到button上呢,自然就是用一个FrameLayout把button和imageview包裹起来,然后将这个layout当作一个weidgt。把一个layout当成一个控件我开始不太理解。后来了解到一些东西。

补充知识点(安卓的顶层视图)
在android里面,你的app界面的活动的视图并非是最顶级的视图。大家应该都知道viewtree。在安卓里面,最顶级的视图是一个叫DecorView的东西。它包括你的状态栏,标题栏,以及你的活动界面。而且这个活动界面,安卓会自动帮你提前弄进去一个FrameLayout。可以这么理解吧,在安卓这个上帝的面前,你的activity就是放在他的framelayout的一个个view。上一张图~

DecorView->LinearLayout(状态栏和activity)->FrameLayout(activity)->你自己的acitivty视图。

实例讲解
好啦,回归正题。我上代码了。
myimagebutton_layout.xml

<FrameLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 <Button
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/button_imagebutton"    />
 <ImageView
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/imageview_button"    />
</FrameLayout>

用一个framelayout把两个控件装起来,然后组合。组合了之后我们就去自定义我们这个控件的属性。button不用变对吧,用原生的就好了,就是需要有一个图片的src这个属性就好了。
在values目录下的attrs.xml文件_

<?xml version="1.0" encoding="utf-8"?>
<resources>在
  <declare-styleable name="MyImageButton">
    <attr name="Imagesrc" format="reference"/>
  </declare-styleable>
</resources>

一般来说,declare-styleable标签的名字都是你的自定义控件的名字。attr就是你的自定义控件属性。format是这个属性的值的数据类型。这里的reference表示引用。dimension表示的是dp或者sp的大小。还有一些可以自己去看看。定义好属性,我们就开始写控件了。
MyImageButton.java

public class MyImageButton2 extends FrameLayout{

  ImageView mImageView;
  Button mButton;
  int resId;

  public MyImageButton2(Context context) {
    super(context);
  }

  public MyImageButton2(Context context, AttributeSet attrs) {
    super(context, attrs);
    //导入布局
    LayoutInflater.from(context).inflate(R.layout.myimagebutton_layout, this);

   mImageView=(ImageView)findViewById(R.id.imageview_button);

   mButton = (Button) findViewById(R.id.button_imagebutton);
    //获得这个控件对应的属性。
   TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyImageButton);

    try{
     //获得属性值
      resId = a.getResourceId(R.styleable.MyImageButton_Imagesrc, 0);
    }finally {
     //回收这个对象
      a.recycle();
    }

    if(resId != 0){
      mImageView.setImageResource(resId);
    }
  }

  public void setImage(int resId){
    mImageView.setImageResource(resId);
  }

}

一般来说,继承view(就这么说吧,反正都是都是继承view的),实现两三个构造函数就可以了。在第二个里面有一个attr,这就是传进来的属性。如果resId不为默认值,就表示用户在xml里面传入了这个属性值,你也必须要写一个set方法,让用户可以在java代码中去改变属性值。
test.myimagebutton.layout.xml_

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <com.example.think.testview.customview.MyImageButton2
    xmlns:pt = "http://schemas.android.com/apk/res/com.example.think.testview"
    android:layout_height="100dp"
    android:layout_width="match_parent"
    pt:Imagesrc = "@drawable/ic_launcher"
    />

</LinearLayout>

效果图

另一个实例

这里我们来看一个view组合控件的例子:

<string-array name="bao_type">
   <item>测试1</item>
   <item>测试2</item>
   <item>测试3</item>
   <item>测试4</item>
 </string-array> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/gray_common_background"
  android:orientation="vertical"> 

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"> 

    <TextView
      android:id="@+id/txt_viewpage_bar1"
      style="@style/style_common_pagebar"
      android:textColor="@color/theme_red" /> 

    <TextView
      android:id="@+id/txt_viewpage_bar2"
      style="@style/style_common_pagebar" /> 

    <TextView
      android:id="@+id/txt_viewpage_bar3"
      style="@style/style_common_pagebar" /> 

    <TextView
      android:id="@+id/txt_viewpage_bar4"
      style="@style/style_common_pagebar" />
  </LinearLayout> 

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"> 

    <View
      android:id="@+id/view_viewpage_bar1"
      style="@style/style_common_pagebar_view" /> 

    <View
      android:id="@+id/view_viewpage_bar2"
      style="@style/style_common_pagebar_view" /> 

    <View
      android:id="@+id/view_viewpage_bar3"
      style="@style/style_common_pagebar_view" /> 

    <View
      android:id="@+id/view_viewpage_bar4"
      style="@style/style_common_pagebar_view" />
  </LinearLayout> 

  <android.support.v4.view.ViewPager
    android:id="@+id/common_viewpage_buttom"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />
</LinearLayout> 
public interface SlbPageViewOnPageChangeListener {
   void onPageSelected(int position); 

   void onPageScrollStateChanged(int state);
 } 
public class SlbPageViewBar extends LinearLayout { 

  private TextView[] mTotalTxtViews;
  private View[] mTotalViews;
  private List<TextView> mTxtViews;
  private List<View> mViews; 

  private ViewPager mViewPager;
  private SlbPageViewOnPageChangeListener mSlbPageViewOnPageChangeListener; 

  public SlbPageViewBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    mTotalTxtViews = new TextView[4];
    mTotalViews = new View[4];
    mTxtViews = new ArrayList<>();
    mViews = new ArrayList<>();
    initView();
  } 

  private void initView() {
    View.inflate(getContext(), R.layout.layout_common_top_pageview_bar, this);
    mViewPager = (ViewPager) findViewById(R.id.common_viewpage_buttom);
    mTotalTxtViews[0] = (TextView) findViewById(R.id.txt_viewpage_bar1);
    mTotalTxtViews[1] = (TextView) findViewById(R.id.txt_viewpage_bar2);
    mTotalTxtViews[2] = (TextView) findViewById(R.id.txt_viewpage_bar3);
    mTotalTxtViews[3] = (TextView) findViewById(R.id.txt_viewpage_bar4);
    mTotalViews[0] = findViewById(R.id.view_viewpage_bar1);
    mTotalViews[1] = findViewById(R.id.view_viewpage_bar2);
    mTotalViews[2] = findViewById(R.id.view_viewpage_bar3);
    mTotalViews[3] = findViewById(R.id.view_viewpage_bar4); 

  } 

  /**
   * @param title 标题名称数组
   */ 

  public void setTitleView(String[] title) {
    int legth = title.length > 4 ? 4 : title.length;
    for (int i = 0; i < legth; i++) {
      mTotalTxtViews[i].setText(title[i]);
      mTotalTxtViews[i].setVisibility(View.VISIBLE);
      mTotalViews[i].setVisibility(View.INVISIBLE);
      mTotalTxtViews[i].setOnClickListener(new SlbTextViewOnLister(i));
      mTxtViews.add(mTotalTxtViews[i]);
      mViews.add(mTotalViews[i]);
    }
    mTotalViews[0].setVisibility(View.VISIBLE);
    mViewPager.setOnPageChangeListener(mOnButtomPageChangeListener);
  } 

  public ViewPager getViewPager(){
    return mViewPager;
  } 

  public void setSlbPageViewOnPageChangeListener(SlbPageViewOnPageChangeListener slbPageViewOnPageChangeListener) {
    this.mSlbPageViewOnPageChangeListener = slbPageViewOnPageChangeListener;
  } 

  private void changeViewBg(int textViewId, int viewId) {
    for (View view : mViews) {
      if (viewId == view.getId()) {
        view.setVisibility(View.VISIBLE);
      } else {
        view.setVisibility(View.INVISIBLE);
      }
    }
    for (TextView view : mTxtViews) {
      if (textViewId == view.getId()) {
        view.setTextColor(getResources().getColor(R.color.theme_red));
      } else {
        view.setTextColor(getResources().getColor(R.color.black_normal_text_33333));
      }
    }
  } 

  class SlbTextViewOnLister implements OnClickListener { 

    private int mItem; 

    public SlbTextViewOnLister(int item) {
      this.mItem = item; 

    } 

    @Override
    public void onClick(View v) {
      mViewPager.setCurrentItem(mItem);
    }
  } 

  private ViewPager.OnPageChangeListener mOnButtomPageChangeListener = new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

    } 

    @Override
    public void onPageSelected(int position) {
      switch (position) {
        case 0:
          changeViewBg(R.id.txt_viewpage_bar1, R.id.view_viewpage_bar1);
          break;
        case 1:
          changeViewBg(R.id.txt_viewpage_bar2, R.id.view_viewpage_bar2); 

          break;
        case 2:
          changeViewBg(R.id.txt_viewpage_bar3, R.id.view_viewpage_bar3);
          break;
        case 3:
          changeViewBg(R.id.txt_viewpage_bar4, R.id.view_viewpage_bar4);
          break;
      }
      if (mSlbPageViewOnPageChangeListener != null)
        mSlbPageViewOnPageChangeListener.onPageSelected(position);
    } 

    @Override
    public void onPageScrollStateChanged(int state) {
      if (mSlbPageViewOnPageChangeListener != null)
        mSlbPageViewOnPageChangeListener.onPageScrollStateChanged(state);
    }
  }; 

} 
public class CommonViewpageAdapter extends FragmentPagerAdapter {
  private List<Fragment> mFragments;
  private String [] mTitles; 

  public CommonViewpageAdapter(FragmentManager fm, List<Fragment> fragments, String [] titles) {
    super(fm);
    mFragments = fragments;
    mTitles = titles;
  } 

  @Override
  public Fragment getItem(int position) {
    return mFragments.get(position);
  } 

  @Override
  public int getCount() {
    return mFragments.size();
  } 

  @Override
  public CharSequence getPageTitle(int position) {
    return mTitles[position];
  } 

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
  }
} 
<com.slfinance.app.slb.common.ui.view.SlbPageViewBar
    android:id="@+id/slbpv_buy_huoqibao_SlbPageViewBarshow"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"/> 
private void initButtomPageFragment(SlbPageViewBar slbPageViewBar) {
  List<Fragment> fragmentList = new ArrayList<>();
  Test1Fragment test1Fragment = new Test1Fragment();
  Test2Fragment test2Fragment = new Test2Fragment();
  Test3Fragment test3Fragment = new Test3Fragment();
  Test4Fragment test4Fragment = new Test4Fragment();
  fragmentList.add(test1Fragment);
  fragmentList.add(test2Fragment);
  fragmentList.add(test3Fragment);
  fragmentList.add(test4Fragment);
  String[] titles = getResources().getStringArray(R.array.buy_huoqi_bao_zanquan_detail);
  slbPageViewBar.setTitleView(titles);
  CommonViewpageAdapter viewPagerAdapter = new CommonViewpageAdapter(
      getSupportFragmentManager(), fragmentList, titles);
  mButtomPageView.setAdapter(viewPagerAdapter);
  mButtomPageView.setOffscreenPageLimit(3);
  mButtomPageView.setCurrentItem(0);
} 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, 安卓
, view
, 自定义属性
组合控件
wpf 自定义控件 实例、自定义组合控件、安卓自定义组合控件、自定义view组合控件、c 自定义组合控件,以便于您获取更多的相关知识。

时间: 2024-10-30 05:30:45

实例讲解Android应用中自定义组合控件的方法_Android的相关文章

Android开发中自定义ProgressBar控件的方法示例

本文实例讲述了Android开发中自定义ProgressBar控件的方法.分享给大家供大家参考,具体如下: 很简单,首先加载Drawable,在onMeasure设置好其区域大小, 然后使用canvas.clipRect绘图 public class ProgressView extends ImageView { private Drawable maskDraw; /** * 加载的进度 0-100 */ private int mProcess = 20; public ProgressV

自定义组合控件问题-自定义组合控件onDraw()方法死循环

问题描述 自定义组合控件onDraw()方法死循环 自定义了一个组合控件,继承自LinearLayout,逻辑很简单,就是想实现一个带title的EditText.为了便于分析问题,已经将代码中的attrs.xml的属性删除,只留下导致问题出现的部分. 自定义控件的JAVA代码: package com.shuda.epmms.customview; import android.content.Context; import android.content.res.TypedArray; im

在Android开发中使用自定义组合控件的例子_Android

一.定义一个XML布局文件setting_item_view.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height=

Android自定义控件之自定义组合控件(三)_Android

前言: 前两篇介绍了自定义控件的基础原理Android自定义控件基本原理详解(一).Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发成本,以及维护成本. 使用自定义组合控件的好处?我们在项目开发中经常会遇见很多相似或者相同的布局,比如APP的标题栏,我们从三种方式实现标题栏来对比自定义组件带来的好处,毕竟好的东西还是以提高开发效率,降低开发成本为导向的. 1.)第一种方式:直接在每个xml布局中写相同的标题栏布局代码  <?xml ve

Android自定义控件之自定义组合控件(三)

前言: 前两篇介绍了自定义控件的基础原理Android自定义控件基本原理详解(一).Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发成本,以及维护成本. 使用自定义组合控件的好处? 我们在项目开发中经常会遇见很多相似或者相同的布局,比如APP的标题栏,我们从三种方式实现标题栏来对比自定义组件带来的好处,毕竟好的东西还是以提高开发效率,降低开发成本为导向的.  1.)第一种方式:直接在每个xml布局中写相同的标题栏布局代码 <?xml v

实例讲解Android中的View类以及自定义View控件的方法_Android

View的简单理解和实例 1.View的基本概念在Activity显示的控件 都叫做View(View类 是所有的控件类的父类  比如 文本 按钮) 2.在Activity当中获取代表View的对象Activity读取布局文件生成相对应的 各种View对象 TextView textView=(TextView)findViewBy(R.id.textView) 3.设置view的属性Activity_mian.xml 这样的xml布局文件中发现了,类似@+id/和@id/到底有什么区别呢? 这

Android中View自定义组合控件的基本编写方法_Android

有很多情况下,我们只要运用好Android给我提供好的控件,经过布局巧妙的结合在一起,就是一个新的控件,我称之为"自定义组合控件". 那么,这种自定义组合控件在什么情况下用呢?或者大家在做项目时候会发现,某些布局会被重复的利用,同一个布局的XML代码块会被重复的复制黏贴多次,这样会造成代码结构混乱不说,代码量也会增大,各种控件都需要在Java代码中被申明和处理相应的逻辑,工作量着实不小,所以,必须要找到一个合理的"偷懒"的方式,开动脑经去怎么简化以上说的不必要的麻烦

WPF中引入WindowsForms控件的方法_C#教程

本文实例讲述了WPF中引入WindowsForms控件的方法.分享给大家供大家参考,具体如下: 环境: [1]WindowsXP with SP3 [2]VS2008 with SP1 正文: Step1:在现有工程中引入Windows Forms 鼠标右键[References]->选择[Add Reference]->[.NET]标签页 加入[WindowsFormsIntegration]和[System.Windows.Forms]两项 Step2:在XAML文件里加入 [S2-1]加

Android自定义组合控件之自定义下拉刷新和左滑删除实例代码_Android

绪论 最近项目里面用到了下拉刷新和左滑删除,网上找了找并没有可以用的,有比较好的左滑删除,但是并没有和下拉刷新上拉加载结合到一起,要不就是一些比较水的结合,并不能在项目里面使用,小编一着急自己组合了一个,做完了和QQ的对比了一下,并没有太大区别,今天分享给大家,其实并不难,但是不知道为什么网上没有比较好的Demo,当你的项目真的很急的时候,又没有比较好的Demo,那么"那条友谊的小船儿真是说翻就翻啊",好了,下面先来具体看一下实现后的效果吧:   代码已经上传到Github上了,小伙伴