2011-05-06 4 views

답변

4

Spinner를 확장하고 AlertDialog의 위치를 ​​변경해야합니다 (클릭하면 alertDialog 역할을합니다).

코드 (, 또한 열 스피너에 대한 배경을 단지 위치보다 조금 더 설정 않음) :

:

public class CustomSpinner extends Spinner { 

private AlertDialog mPopup; 

public CustomSpinner(Context context) { 
    super(context); 
} 

public CustomSpinner(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public CustomSpinner(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

@Override 
protected void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
} 

@Override 
protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 

    if (mPopup != null && mPopup.isShowing()) { 
     mPopup.dismiss(); 
     mPopup = null; 
    } 
} 


//when clicked alertDialog is made 
@Override 
public boolean performClick() { 
    Context context = getContext(); 

    AlertDialog.Builder builder = new AlertDialog.Builder(context); 
    CharSequence prompt = getPrompt(); 
    if (prompt != null) { 
     builder.setTitle(prompt); 
    } 



    mPopup = builder.setSingleChoiceItems(
      new DropDownAdapter(getAdapter()), 
      getSelectedItemPosition(), this).show(); 

    WindowManager.LayoutParams WMLP = mPopup.getWindow().getAttributes(); 

      //width and height must be set to anything other than WRAP_CONTENT! 
    WMLP.x = 0; // x position 
    WMLP.y = 50; // y position 
    WMLP.height =390 ; //LayoutParams.WRAP_CONTEN 
    WMLP.width = 315; 
    WMLP.horizontalMargin = 0; 
    WMLP.verticalMargin = 0; 

    mPopup.getWindow().setAttributes(WMLP); 



    //ListView.getDefaultSize(size, measureSpec) 
    ListView listView = mPopup.getListView(); 
    //listView.set 
    // Remove divider between rows 
    listView.setDivider(null); 

    // Set custom background 
    listView.setBackgroundResource(R.drawable.drop); 

    // Remove background from all (grand)parent's 
    ViewParent parent = listView.getParent(); 
    while (parent != null && parent instanceof View) { 
     ((View) parent).setBackgroundDrawable(null); 

     parent = parent.getParent(); 
    } 

    return true; 
} 

@Override 
public void onClick(DialogInterface dialog, int which) { 
    setSelection(which); 
    dialog.dismiss(); 
    mPopup = null; 
} 


* <p>Wrapper class for an Adapter. Transforms the embedded Adapter instance 
* into a ListAdapter.</p> 
*/ 
private static class DropDownAdapter implements ListAdapter, SpinnerAdapter { 
    private SpinnerAdapter mAdapter; 

    /** 
    * <p>Creates a new ListAddapter wrapper for the specified adapter.</p> 
    * 
    * @param adapter the Adapter to transform into a ListAdapter 
    */ 
    public DropDownAdapter(SpinnerAdapter adapter) { 
     this.mAdapter = adapter; 
    } 

    public int getCount() { 
     return mAdapter == null ? 0 : mAdapter.getCount(); 
    } 

    public Object getItem(int position) { 
     return mAdapter == null ? null : mAdapter.getItem(position); 
    } 

    public long getItemId(int position) { 
     return mAdapter == null ? -1 : mAdapter.getItemId(position); 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     return getDropDownView(position, convertView, parent); 
    } 

    public View getDropDownView(int position, View convertView, ViewGroup parent) { 
     return mAdapter == null ? null : 
       mAdapter.getDropDownView(position, convertView, parent); 
    } 

    public boolean hasStableIds() { 
     return mAdapter != null && mAdapter.hasStableIds(); 
    } 

    public void registerDataSetObserver(DataSetObserver observer) { 
     if (mAdapter != null) { 
      mAdapter.registerDataSetObserver(observer); 
     } 
    } 

    public void unregisterDataSetObserver(DataSetObserver observer) { 
     if (mAdapter != null) { 
      mAdapter.unregisterDataSetObserver(observer); 
     } 
    } 

    /** 
    * <p>Always returns false.</p> 
    * 
    * @return false 
    */ 
    public boolean areAllItemsEnabled() { 
     return true; 
    } 

    /** 
    * <p>Always returns false.</p> 
    * 
    * @return false 
    */ 
    public boolean isEnabled(int position) { 
     return true; 
    } 

    public int getItemViewType(int position) { 
     return 0; 
    } 

    public int getViewTypeCount() { 
     return 1; 
    } 

    public boolean isEmpty() { 
     return getCount() == 0; 
    } 

    } 
    } 

그런 다음 당신은 그냥 돼 같은 "yourPackage.CustomSpinner"요소와 레이아웃에 삽입

<yourPackage.CustomSpinner 
    android:layout_height="wrap_content" 
    android:id="@+id/spinner" 
    android:layout_width="fill_parent"> 
</yourPackage.CustomSpinner> 
25

은 드롭 다운으로 스피너 모드를 선언 :

android:spinnerMode="dropdown" 

후 사용 수직 격차를 오프셋 : 당신이 이것을 사용할 수 있습니다

android:dropDownVerticalOffset="-15dp" 

Spinner Android Documentation

+2

-15dp를 어떻게 사용 했습니까? –

+1

그게 전부입니다. 나는 두려워하는 마법의 숫자입니다. 정확한 번호를 얻으려면 시행 착오를 거쳐야합니다/구현을 찾으십시오. – Tr0yJ

+0

정말 고마워 ... 나를 위해 일한 ... –

0

드롭 다운 스피너 모드의 경우 :

mSortingSpinner.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
     mSortingSpinner.setDropDownVerticalOffset(
       mSortingSpinner.getDropDownVerticalOffset() + mSortingSpinner.getHeight()); 
     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { 
      mSortingSpinner.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
     } else { 
      mSortingSpinner.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
     } 
    } 
}); 

세트 수직 스피너 높이 드롭 다운의 오프셋 (offset)입니다.

관련 문제