我正在写一个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;
}
}
第二个问题是:有没有办法把下拉列表放在微调器的下边缘而不是上边缘?
感谢任何能给我帮助或答案的人。我为我糟糕的英语道歉。。。
暂无答案!
目前还没有任何答案,快来回答吧!