xamarin android自定义spinner

简介: 以前弄的一个下拉框时自带的spinner,感觉好丑,实际效果实在满足不了基本的UI界面要求,还是自己动手丰衣足食,看了网上关于android中自定义spinner的文章,感觉实现原理还是比较简单,所以这里用xamarin android来实现自定义spinner样式。

以前弄的一个下拉框时自带的spinner,感觉好丑,实际效果实在满足不了基本的UI界面要求,还是自己动手丰衣足食,看了网上关于android中自定义spinner的文章,感觉实现原理还是比较简单,所以这里用xamarin android来实现自定义spinner样式。参考文章:http://blog.csdn.net/jdsjlzx/article/details/41316417

实现原理
1.TextView中显示选择的内容,右边显示上下的箭头,点击事件中设置不同的箭头
2.TextView下显示的是一个PoputWindow,PoputWindow中显示的自定义ListView,在TextView单击事件中显示ListView就是下拉的选择项。
先来看看最终的效果图
这里写图片描述

代码实现的过程主要分为以下几个部分:

  1. MainActivity布局实现(这个就是一个TextView)
  2. PoputWindow布局和ListView布局实现
  3. 自定类SpinerPopWindow继承PoputWIndow的实现,ListView适配器类的实现(实现的关键)
  4. MainActivity.cs中TextView事件监听、ListView的Item单击事件的监听实现

1. MainActivity布局实现

MainActivity中只有一个TextView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingRight="20dp"
     android:background="@color/color_ffffff"
    android:paddingLeft="20dp">
    <TextView
        android:id="@+id/tv_value"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/color_dedede"
        android:drawableRight="@drawable/icon_down"
        android:padding="10dp"
        android:textColor="@color/content_color"
        android:textSize="20sp" />
</LinearLayout>

2.PoputWindow布局和ListView布局实现

1.PoputWindow里面放的是一个ListView控件。spinner_window_layout.xml的background需要添加边框、设置背景颜色

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:orientation="vertical">
    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:background="@drawable/shape_popupwindow_list_bg"
        android:scrollbars="none" >
    </ListView>
</LinearLayout>

2.ListView布局文件spinner_item_layout里面只有一个TextView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical">
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="fdsfdsfdsf"
        android:textSize="20sp"/>
</LinearLayout>

3.自定类SpinerPopWindow继承PoputWIndow的实现,ListView适配器类的实现(实现的关键)

spinnerPopWindow.cs需要继承PoputWindow,初始化ListView。ListView的Adapter类LVAdapter就不多说了。

using System.Collections.Generic;
using System.Linq;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Graphics.Drawables;
using static Android.Views.ViewGroup;
namespace customSpinnerDemo
{
    public  class SpinerPopWindow<T>:PopupWindow
    {
        private ListView listView;
        private List<T> list;
        private LVAdapter<T> adapter;
        private Context context;
        private LayoutInflater inflater;
        public SpinerPopWindow(Context _context ,List<T> _list, AdapterView.IOnItemClickListener itemClickListener)
        {
            context = _context;
            list = _list;
            inflater = LayoutInflater.From(_context);
            InitListView(itemClickListener);
        }
        private void InitListView(AdapterView.IOnItemClickListener itemClickListener)
        {
            View view = inflater.Inflate(Resource.Layout.spiner_window_layout, null);
            this.ContentView = view;
            //LayoutParams
            var parentView = (ViewGroup)view;
            var child  = parentView.GetChildAt(0);
            this.Width = LayoutParams.WrapContent;
            this.Height = LayoutParams.WrapContent;
            this.Focusable = true;
            ColorDrawable cdw = new ColorDrawable(Android.Graphics.Color.Transparent);
            SetBackgroundDrawable(cdw);
            //View childView = ContentView

            listView = view.FindViewById<ListView>(Resource.Id.listview);
            adapter = new customSpinnerDemo.LVAdapter<T>(context,list);
            listView.Adapter = adapter;
            listView.OnItemClickListener = itemClickListener;
        }
    }
    public class LVAdapter<T> : BaseAdapter
    {
        private List<T> list;
        private Context context;
        public LVAdapter(Context _context,List<T> _list)
        {
            context = _context;
            list = _list;
        }
        public override int Count
        {
            get{
                return list.Count();
            }
        }
        public override Java.Lang.Object GetItem(int position)
        {
            return null;
        }
        public override long GetItemId(int position)
        {
            return position;
        }
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            ViewHolder holder = null;
            if (convertView == null)
            {
                holder = new ViewHolder();
                convertView = LayoutInflater.From(context).Inflate(Resource.Layout.spiner_item_layout,parent,false);
                holder.tvName = convertView.FindViewById<TextView>(Resource.Id.tv_name);
                convertView.Tag = holder;
            }
            else
            {
                holder = (ViewHolder)convertView.Tag;
            }
            holder.tvName.Text = list[position].ToString();
            return convertView; 
        }
        private class ViewHolder:Java.Lang.Object {
            internal TextView tvName;
        }
    }
}

4.MainActivity.cs中TextView事件监听、ListView的Item单击事件的监听实现
实现的原理就是一下代码了

using Android.App;
using Android.Widget;
using Android.OS;
using System.Collections.Generic;
using static Android.Widget.AdapterView;
using Android.Views;
using Android.Graphics.Drawables;
using Android.Support.V7.App;
namespace customSpinnerDemo
{
    [Activity(Label = "customSpinnerDemo", MainLauncher = true, Icon = "@drawable/icon",Theme = "@style/AppTheme")]
    public class MainActivity : AppCompatActivity, IOnItemClickListener, PopupWindow.IOnDismissListener
    {
        private List<string> list;
        private TextView tv_value;
        private SpinerPopWindow<string> SpinnerPopwindow;
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView (Resource.Layout.Main);
            tv_value = FindViewById<TextView>(Resource.Id.tv_value);
            tv_value.Click += (s,e) =>
            {
                SpinnerPopwindow.Width = tv_value.Width;
                SpinnerPopwindow.ShowAsDropDown(tv_value);
                SetTextImage(Resource.Drawable.icon_up);
            };
            list = new List<string>() { "科比","詹姆斯","韦德","波什"};
            SpinnerPopwindow = new SpinerPopWindow<string>(this,list,this);
            SpinnerPopwindow.SetOnDismissListener(this);
        }
        /// <summary>
        /// 给TextView右边设置图片
        /// </summary>
        private void SetTextImage(int resId)
        {
            //var drawable =GetDrawable(resId);
            Drawable drawable = Resources.GetDrawable(resId);
            drawable.SetBounds(0,0,drawable.MinimumWidth,drawable.MinimumHeight);
            tv_value.SetCompoundDrawables(null,null,drawable,null);
        }
        /// <summary>
        /// popupWindow 显示的ListView的item点击事件
        /// </summary>
        public void OnItemClick(AdapterView parent, View view, int position, long id)
        {
            SpinnerPopwindow.Dismiss();
            tv_value.Text=list[position].ToString();
            Toast.MakeText(this,"点击了:"+list[position],ToastLength.Long).Show();
        }
        /// <summary>
        /// popupWindow取消
        /// </summary>
        public void OnDismiss()
        {
            SetTextImage(Resource.Drawable.icon_down);
        }
    }
}

小结

虽然实现原理比较简单,但是要把一个下拉框做的能够调用简单,代码多处复用,代码量小而简单,还是需要琢磨的。

,如果代码有什么看不懂的地方,直接看Github吧:https://github.com/MaChuZhang/Xamarin-Android-Custom-View
作者:张林
标题:xamarin android自定义spinner 原文地址:http://blog.csdn.net/kebi007/article/details/74856836
转载随意注明出处

目录
相关文章
|
7天前
|
Java API 调度
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
34 0
|
7天前
|
存储 Java Linux
Android Mstar增加IR 自定义遥控头码完整调试过程
Android Mstar增加IR 自定义遥控头码完整调试过程
21 1
|
21天前
|
缓存 测试技术 Android开发
深入探究Android中的自定义View绘制优化策略
【4月更文挑战第8天】 在Android开发实践中,自定义View的绘制性能至关重要,尤其是当涉及到复杂图形和动画时。本文将探讨几种提高自定义View绘制效率的策略,包括合理使用硬件加速、减少不必要的绘制区域以及利用缓存机制等。这些方法不仅能改善用户体验,还能提升应用的整体性能表现。通过实例分析和性能测试结果,我们将展示如何有效地实现这些优化措施,并为开发者提供实用的技术指南。
|
27天前
|
前端开发 Android开发 开发者
深入探究Android中的自定义View组件开发
【4月更文挑战第3天】 在现代Android应用程序的开发过程中,创建具有独特功能和高度定制化的用户界面是一个常见需求。为此,理解并掌握自定义View组件的开发成为了开发者必备的技能之一。本文将深入探讨如何在Android中创建自定义View,从基础的绘制原理到事件处理机制,再到性能优化技巧,旨在为读者提供一个全面的技术视角,并通过实例代码演示如何实现一个功能丰富、响应迅速的自定义View组件。
|
28天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
55 1
|
7天前
|
Android开发 芯片
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
24 3
|
7天前
|
移动开发 Java Unix
Android系统 自动加载自定义JAR文件
Android系统 自动加载自定义JAR文件
24 1
|
7天前
|
Shell Android开发 开发者
Android系统 自定义动态修改init.custom.rc
Android系统 自定义动态修改init.custom.rc
23 0
|
7天前
|
存储 安全 Android开发
Android系统 自定义系统和应用权限
Android系统 自定义系统和应用权限
19 0
|
18天前
|
XML 数据可视化 Android开发
深入探究Android中的自定义View组件开发
【4月更文挑战第12天】在安卓应用开发中,创建具有独特交互和视觉表现的自定义View组件是增强用户体验的重要手段。本文将详细阐述如何从头开始构建一个Android自定义View,包括理解View的工作原理、处理绘制流程、事件分发机制以及属性的自定义与管理。通过具体案例分析,我们将一步步实现一个可定制的动态进度条,不仅具备基础功能,还能根据业务需求进行扩展,体现高度的产品个性化。