• [置顶] 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);
            }
        }
    }

    小结

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

  • 相关阅读:
    图的邻接链表实现(c)
    图的邻接矩阵实现(c)
    好文
    第13章 红黑树
    函数 setjmp, longjmp, sigsetjmp, siglongjmp
    域名解析
    wget www.baidu.com执行流程分析
    信号处理篇
    第11章 散列表
    第10章,基本数据结构(栈,队列)
  • 原文地址:https://www.cnblogs.com/zhangmumu/p/7374764.html
Copyright © 2020-2023  润新知