自定义view MySpinner(个人纪录)

本文介绍了一个自定义的 Spinner 组件 MySpinner 的实现,它继承自 AppCompatButton,并实现了 PopupWindow 的功能。MySpinner 支持在顶部显示选项列表,包含了设置背景、监听选择项、自适应宽度等功能。
package com.wbm.app.utils.ui;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;

import com.wbm.app.activity.R;
import com.wbm.app.business.model.CategoryDTO;
import com.wbm.app.fragment.express.ExpressFragment;
import com.wbm.app.utils.ui.shadowviewhelper.ShadowProperty;
import com.wbm.app.utils.ui.shadowviewhelper.ShadowViewHelper;

/**
 * Created by Kodulf on 16/6/27.
 */
public class MySpinner extends android.support.v7.widget.AppCompatButton implements PopupWindow.OnDismissListener {
    private PopupWindow popupWindow;
    private BaseAdapter adapter;
    private ListView lv;
    private int selection;

    private MyItemSelectedListener itemSelectedListener;

    private int lvWidth;
    private int bgClose;
    private int bgOpen;
    /**
     * 是否popupwindow显示在上面
     */
    private boolean showPopupWindowInTop = false;

    private Handler handler;

    public MySpinner(Context context) {
        super(context);
        init(context);

    }

    public MySpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(attrs!=null){
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MySpinner);
            showPopupWindowInTop = typedArray.getBoolean(R.styleable.MySpinner_show_popupwindow_in_top, false);
        }
        init(context);
    }

    public MySpinner(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if(attrs!=null){
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MySpinner);
            showPopupWindowInTop = typedArray.getBoolean(R.styleable.MySpinner_show_popupwindow_in_top, false);
        }
        init(context);
    }

    private void init(final Context context) {

        handler=new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if(msg.what==1){
                    setClickable(true);
                }
                return false;
            }
        });


//        View v= LayoutInflater.from(context).inflate(R.layout.view_pop,null);
        lv= new ListView(context);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selection=position;
                chengeText();
                if(popupWindow!=null){
                    popupWindow.dismiss();
                }
                if(itemSelectedListener!=null){
                    itemSelectedListener.onItemSelected(position);
                }
            }
        });
        ShadowViewHelper.bindShadowHelper(new ShadowProperty().setShadowColor(0x30000000).setShadowRadius(5), lv,5,5);
        popupWindow=new PopupWindow(lv,lvWidth==0? LinearLayout.LayoutParams.WRAP_CONTENT:lvWidth,LinearLayout.LayoutParams.WRAP_CONTENT);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.shape_write_for_pop));
        popupWindow.setOnDismissListener(this);


        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(adapter!=null && adapter.getCount() >0) {
                    setBackgroundResource(bgOpen);
                    //如果是要显示在上面的,那么直接设置location
                    if(showPopupWindowInTop){
                        int[] location  = new int[2];
                        getLocationInWindow(location);
                        int x  = location[0];
                        int y = location[1];
                        //显示在popupwindow的正上方
                        popupWindow.showAtLocation(MySpinner.this, Gravity.TOP|Gravity.LEFT, x,y);
                    }else {
                        if (top == null) {
                            popupWindow.showAsDropDown(MySpinner.this, 0, context.getResources().getDimensionPixelOffset(R.dimen.y_px8));
                        } else {
                            popupWindow.showAsDropDown(MySpinner.this, 0, top);
                        }
                    }
                }
            }
        });

    }

    private Integer top;
    public void setMarginTop(Integer t){
        top=t;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int specSize=MeasureSpec.getSize(widthMeasureSpec);
        int specMode=MeasureSpec.getMode(widthMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            lvWidth = specSize;
        } else {
            lvWidth=getPaddingLeft()+getPaddingRight()+getWidth();
        }
        if(popupWindow!=null){
            popupWindow.setWidth(lvWidth);
        }
    }

    public void setAdapter(BaseAdapter adapter){
        this.adapter=adapter;
        lv.setAdapter(adapter);
        chengeText();
    }


    /**
     * popupwindow消失的监听
     */
    @Override
    public void onDismiss() {
        setClickable(false);
        handler.sendEmptyMessageDelayed(1,100);
        if(bgClose!=0){
            setBackgroundResource(bgClose);
        }
    }

    public void setSelection(int selection){
        this.selection=selection;
        chengeText();
    }

    public int getSelectedItemPosition(){
        return selection;
    }

    private void chengeText(){
        try {
            if(selection>=0&&adapter!=null && adapter.getCount()>selection) {
                Log.d("kodulf", "adpter.get"+adapter.getItem(selection));
                Object obj = adapter.getItem(selection);
                if(obj instanceof ExpressFragment.ExpressCompany){
                    ExpressFragment.ExpressCompany expressCompany = (ExpressFragment.ExpressCompany)obj;
                    String express_cop_short_name = expressCompany.getExpress_cop_short_name();
                    setText(express_cop_short_name);
                }else if(obj instanceof CategoryDTO){
                    CategoryDTO categoryDTO= (CategoryDTO) obj;
                    setText(categoryDTO.getName());
                }else {
                    setText((CharSequence) adapter.getItem(selection));
                }
            }else{
                setText(null);
            }
        }catch (Exception e){

        }

    }

//    public void setLvWidth(int width){
//        lvWidth=width;
//        if(popupWindow!=null){
//            popupWindow.setWidth(lvWidth);
//        }
//    }

    public void setBg(int bgOpen,int bgClose){
        this.bgClose=bgClose;
        this.bgOpen=bgOpen;
        if(popupWindow!=null && popupWindow.isShowing()){
            setBackgroundResource(bgOpen);
        }else{
            setBackgroundResource(bgClose);
        }
    }


    public void setOnItemSelectedListener(MyItemSelectedListener listener){
        itemSelectedListener=listener;
    }

    public interface MyItemSelectedListener{
        void onItemSelected(int position);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值