java:spinner ownerdraw不关闭下拉列表

3htmauhk  于 2021-06-29  发布在  Java
关注(0)|答案(0)|浏览(314)

我正在写一个android java应用程序,我不得不写一个颜色选择器,然后我选择微调器解决方案。我准备了两个布局,一个用于微调器,另一个用于下拉列表。因为我需要根据选择修改布局的外观,所以我必须自定义arrayadapter类来管理下拉列表的设计。

public class CColorPicker<T extends Integer> extends ArrayAdapter implements SpinnerAdapter {

我必须说,一切似乎工作,它不会给问题,它画得很完美(虽然我还没有完善的图形方面),甚至点击被截获没有问题。。。。但是,我有一个问题,我一直无法解决。关闭下拉列表。

其行为应该是,如果我'点击'的颜色,它被选中,并关闭下拉列表,否则按下按钮旁边的颜色,它打开了颜色对话框,下拉列表不关闭,当你退出颜色对话框,在列表中的颜色被替换为所选的一个。

因此,在做了各种尝试之后,我决定自己编写所有内容,并定制了一个从“linearlayout”派生的控件,因此我管理了单击并直接打开“颜色”对话框。然而,我不能忍受不知道解决方案是否存在,而且我还没有找到它。显然,我可以定制spinner类,但这将是一项艰巨的工作,而且在任何情况下,结果都将与获得的结果相似。
所以,这里有两个问题,第一个当然是“如何关闭下拉列表?”显然,我已经尝试过“setpressed”和“clearfocus”两种方法,但它们都不起作用。。我仍然可以说'点击'外的下拉关闭,所以问题是程序或我的一部分的错误。。。你知道吗?以下是消息来源。
微调器\u color\u edit.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/color_container"
    android:layout_weight="1"
    android:layout_gravity="center"
    android:background="@color/browser_actions_divider_color"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/single_color"
        android:padding = "0dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/design_default_color_error"
        />
    <TextView
        android:id="@+id/color_hexvalue"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="4dp"
        android:layout_marginBottom="4dp"
        android:textSize="10sp"
        android:gravity="center"
        android:textAlignment="center"
        android:text="#000000"
        />
</FrameLayout>

微调器颜色组合.xml

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/color_selector"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/browser_actions_divider_color"
        android:orientation="horizontal">
        <FrameLayout
            android:id="@+id/color_container"
            android:layout_weight="1"
            android:layout_gravity="center"
            android:background="#e1e1e1"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </FrameLayout>
        <Button
            android:id="@+id/button_changecolor"
            android:layout_width="match_parent"
            android:layout_weight="3"
            android:layout_height="wrap_content"
            android:text="@string/editcol" />
</LinearLayout>

微调器自定义例程

/*ids:  Spinner id
color: actual sselected color

* /

private void prepareColorSpinner(Context ctx,int ids,int color){
    Spinner spinner = (Spinner) findViewById(ids);
    CColorPicker<Integer> langAdapter = new CColorPicker<Integer>(ctx,R.layout.spinner_color_edit, tinte);
    langAdapter.setSelectedColor(color);
    langAdapter.setDropDownViewResource(R.layout.spinner_color_combo);
    langAdapter.setParentSpinner(ids,spinner); //For the color update
    spinner.setAdapter(langAdapter);
}

ccolorpicker.java类

public class CColorPicker<T extends Integer> extends ArrayAdapter implements SpinnerAdapter {
    private class ColorElement extends LinearLayoutCompat {
        private Context mCtx;
        private int mSelectedColor = 0;
        private int RAGGIO;
        public int getSelectedColor(){return mSelectedColor;}
        public void setSelectedColor(int col){mSelectedColor =col;}
        private int mMarginePx = 0; //Margine in pixels
        public int getMargineinPx(){return mMarginePx;}
        public void setMargineinPx(int px){mMarginePx =px;}
        public void setMargineinDp(int dp){mMarginePx = Util.getDp2Px(mCtx.getResources(),dp);}
        private RectF rfext,rfint;
        //Derivo tutti i costruttori del LinearLayoutCompat
        //Li metto per non avere i warnings
        public ColorElement(Context ctx){super(ctx);mCtx = ctx;prepare();}
        public ColorElement(Context ctx, AttributeSet as){super(ctx,as);mCtx = ctx;prepare();}
        public ColorElement(Context ctx, AttributeSet as, int dsa){super(ctx,as,dsa);mCtx = ctx;prepare();}
        public void prepare(){
            RAGGIO = Util.getDp2Px(mCtx.getResources(),2);
        }

        @Override
        public void onDraw(Canvas canvas){
            //Se lo sfondo non è settato, o è trasparente, non chiama la OnDraw
           super.onDraw(canvas);
            Paint p = new Paint();
            int w = canvas.getWidth();
            int h = canvas.getHeight();
            int fullcolor = (getSelectedColor() & 0xFFFFFF) | 0xFF000000;
            p.setColor(fullcolor);
            //Rettangolo colore
            if (rfext == null){
                rfext = new RectF(getMargineinPx(),getMargineinPx(),
                        w-getMargineinPx(),
                        h-getMargineinPx());
            }
            if (rfint == null){
                int intmr = Util.getDp2Px(mCtx.getResources(),RAGGIO)+getMargineinPx();
                rfint = new RectF(intmr,intmr,w-intmr,h-intmr);
            }
            float ray = Util.getDp2Px(mCtx.getResources(),RAGGIO);
            canvas.drawRoundRect(rfext,ray,ray,p);
            p.setColor(Color.WHITE);
            canvas.drawRoundRect(rfint,ray,ray,p);
            p.setColor((fullcolor & 0xFFFFFF) | 0x64000000);
            canvas.drawRoundRect(rfint,ray,ray,p);
            //Testo nel centro
            Rect bounds = new Rect();
            p.setAntiAlias(true);
            p.setTextSize(40);
            String bf = String.format("#%06X",(fullcolor&0xFFFFFF));
            p.getTextBounds(bf, 0, bf.length(), bounds);
            p.setTypeface(Typeface.DEFAULT_BOLD);
            p.setColor(0xff000000);                                        //seleziona colore nero
            bounds.offset(0, -bounds.top);
            int dmx = (w-bounds.width())/2;
            int dmy = (h-bounds.height())/2;
            canvas.drawText(bf, dmx, h-dmy, p);          //stampa il testo

        }
    }
    private final List<T> mColorListts; // android.graphics.Color list
    private Context mCtx ;
    private int MARGINE_INTORNO = 5;
    private AppCompatActivity mApp;
    private int mDropLayId;
    private int mLayId;
    private int mSelectedColor = 0;
    public int getSelectedColor(){return mSelectedColor;}
    public void setSelectedColor(int col){mSelectedColor =col;}
    private int mSpinnerId = -1;
    private Spinner mSpinnerObj;
    public int getParentSpinner(){return mSelectedColor;}
    public void setParentSpinner(int id, Spinner sp){mSpinnerId = id; mSpinnerObj = sp;}
    /*
        Warning inconsistente
        CColorPicker.java:49: warning: [unchecked] unchecked call to ArrayAdapter(Context,int,List<T>) as a member of the raw type ArrayAdapter
        super(context, lay, objects);
             ^
        where T is a type-variable:
        T extends Object declared in class ArrayAdapter
     */
    @SuppressWarnings("unchecked")
    public CColorPicker(Context context,int lay ,List<T> objects) {
        super(context, lay, objects);
        mCtx = context;
        if (mCtx instanceof AppCompatActivity)
            mApp = (AppCompatActivity)mCtx;
        mColorListts = objects;
        mLayId = lay;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        //super.getDropDownView(position, convertView, parent);
        View rowView = convertView;
        try {
            if (rowView == null) {
                // Get a new instance of the row layout view
                LayoutInflater inflater = mApp.getLayoutInflater();
                rowView = inflater.inflate(mDropLayId, null);
                rowView.setTag(R.string.ColorPicker_itemPos,position);
                rowView.setTag(R.string.ColorPicker_color,position);
                FrameLayout flt = rowView.findViewById(R.id.color_container);
                ColorElement ce = new ColorElement(mCtx);
                ce.setMargineinDp(MARGINE_INTORNO);
                ce.setSelectedColor(mColorListts.get(position));
                ce.setId(R.id.single_color);
                //Se lo sfondo non è settato, non chiama la OnDraw
                //Uso un colore definito nelle risorse Grigio
                ce.setBackgroundColor(mCtx.getResources().getColor(R.color.grigioSfondo,null));
                flt.addView(ce);
                //Come faccio a sapere che spinner ha chiesto il popup?
                //Sarà parent?
                setColorSelectionManager(rowView,parent);
            }
        } catch (IllegalArgumentException | NullPointerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rowView;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
        try {
            if (rowView == null) {
                LayoutInflater inflater = mApp.getLayoutInflater();
                rowView = inflater.inflate(mLayId, null);
            }
            cambiaEditAspetto(position,rowView, getSelectedColor());
        } catch (IllegalArgumentException | NullPointerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rowView;
    }

    public void setColorSelectionManager(View rowView, ViewGroup parent) {
        try {
            Button btn = rowView.findViewById(R.id.button_changecolor);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ColorElement ce = v.findViewById(R.id.single_color);
                    if (ce != null){
                        setSelectedColor(ce.getSelectedColor());
                        Util.Output((AppCompatActivity)(getContext()),"Cambio colore = "+getSpinnerName()+"\n-- Colore "+String.format("#%06X",(getSelectedColor()&0xFFFFFF)));
                    }
                }
            });
            View colview = rowView.findViewById(R.id.color_container);
            colview.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ColorElement ce = v.findViewById(R.id.single_color);
                    if (ce != null){
                        setSelectedColor(ce.getSelectedColor());
                        Util.Output((AppCompatActivity)(getContext()),"Cambio colore = "+getSpinnerName()+"\n-- Colore "+String.format("#%06X",(getSelectedColor()&0xFFFFFF)));
                        mSpinnerObj.setPressed(false);
                        ViewParent papi = rowView.getParent();
                        parent.setVisibility(View.INVISIBLE);
                    }
                }
            });
        } catch (IllegalArgumentException | NullPointerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //public void cambiaAspetto(int position, View padre, int colore) {
    public void cambiaAspetto(View col,TextView tv, int colore) {
        try {
            int fullcolor = (colore & 0xFFFFFF) | 0xFF000000;
            if (col != null) {
                col.setBackgroundColor(fullcolor);
            }
            if (tv != null) {
                tv.setText(String.format("#%06X",(colore&0xFFFFFF)));
            }
        } catch (IllegalArgumentException | NullPointerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void cambiaDropAspetto(int position, View padre, int colore) {
        try {
            if (padre != null) {
                int fullcolor = (colore & 0xFFFFFF) | 0xFF000000;
                ColorElement v = padre.findViewById(R.id.single_color);
                v.setBackgroundColor(fullcolor);
                TextView tv = padre.findViewById(R.id.color_hexvalue);
                tv.setText(String.format("#%X",colore));
//                cambiaAspetto(v,tv,colore);
            }
        } catch (IllegalArgumentException | NullPointerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void cambiaEditAspetto(int position, View padre, int colore) {
        try {
            if (padre != null) {
                View v = padre.findViewById(R.id.single_color);
                TextView tv = padre.findViewById(R.id.color_hexvalue);
                cambiaAspetto(v,tv,colore);
            }
        } catch (IllegalArgumentException | NullPointerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private String getSpinnerName(){
        switch (mSpinnerId){
            case R.id.spinner2:
                return "spinner2";
            case R.id.spinner3:
                return "spinner3";
            case R.id.spinner4:
                return "spinner4";
            case R.id.spinner5:
                return "spinner5";
            case R.id.spinner6:
                return "spinner6";
            case R.id.spinner7:
                return "spinner7";
            default:
                return "-- nessuno --";
         }
    }

    @Override
    public void setDropDownViewResource(int droplay){
        super.setDropDownViewResource(droplay);
        mDropLayId = droplay;
    }
}

第二个问题是:有没有办法把下拉列表放在微调器的下边缘而不是上边缘?
感谢任何能给我帮助或答案的人。我为我糟糕的英语道歉。。。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题