2011-08-10 5 views
1

スピナードロップダウンリストにフッターを追加する方法はありますか?たとえば、私がデータベースからスピナーを投入しているとしますが、リストの配置方法に関係なく、リストの一番下に選択が必要です。リストは「データベース項目1、2、...、3 ...」であり、リストの下部には「データベースに項目を追加」というフッターの選択肢があります。Android Spinner Footer

次のようにこれまでのところ、私はあなたのCustomSpinnerクラスを使用していますができます

public class GrainListAdapter extends SimpleCursorAdapter { 

private static final String DEFAULT_UNITS = "American"; 
private Button upButton; 
private Context myContext; 
private RecipeGrainActivity parentActivity; 
private Button downButton; 
private String units; 
private double getLbs; 

public GrainListAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { 
    super(context, layout, c, from, to); 
    myContext = context; 
    parentActivity = (RecipeGrainActivity) myContext; 

    //Checks for metric pref. 
    SharedPreferences myPrefs = PreferenceManager.getDefaultSharedPreferences(context); 
    units = String.valueOf(myPrefs.getString(context.getString(R.string.pref_measurement), DEFAULT_UNITS)); 
} 

@Override 
public void bindView(View view, Context context, Cursor cursor) { 
    int idColumn = cursor.getColumnIndex("_id"); 
    final int getId = cursor.getInt(idColumn); 
    final double increment = 0.25; 

    UnitsConversions convert = new UnitsConversions(); 

    int nameColumn = cursor.getColumnIndex("name"); 
    String getName = cursor.getString(nameColumn); 
    TextView name = (TextView)view.findViewById(R.id.GrainName); 
    name.setText(getName); 

    int originColumn = cursor.getColumnIndex("origin"); 
    String getOrigin = cursor.getString(originColumn); 
    TextView origin = (TextView)view.findViewById(R.id.GrainOrigin); 
    origin.setText(getOrigin); 

    if(units.equals("Metric")){ 
     //Sets labels to metric. 
     String kilos = context.getResources().getString (R.string.kilograms); 
     TextView weightLabel = (TextView)view.findViewById(R.id.GrainLbsLabel); 
     weightLabel.setText(kilos); 
    } 


} 

@Override 
public View newView(Context context, Cursor cursor, final ViewGroup parent) { 
    View view = View.inflate(context, R.layout.grain_list_item, null); 
    return view; 
} 

}

:私はこのような別のアダプタを使用したいと思っています

public class CustomSpinner extends Spinner implements OnItemClickListener { 

private AlertDialog myDialog = null; 
private OnClickListener myButtonClickListener = null; 
private GrainSpinnerAdapter adapter = null; 

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

public void setButtonClickListener(OnClickListener listener) { 
    myButtonClickListener = listener; 
} 

public void setAdapter(GrainSpinnerAdapter adapter){ 
    this.adapter = adapter; 
} 

@Override 
public boolean performClick() { 
    Context context = getContext(); 

    //Inflate the layout 
    final LayoutInflater inflater = LayoutInflater.from(getContext()); 
    final View v = inflater.inflate(R.layout.my_custom_spinner, null); 

    // set up list view 
    final ListView lv = (ListView) v.findViewById(R.id.list); 
    lv.setAdapter(adapter); 
    lv.setSelection(getSelectedItemPosition()); 
    lv.setOnItemClickListener(this); 

    // set up button 
    final Button btn = (Button) v.findViewById(R.id.addButton); 
    btn.setOnClickListener(myButtonClickListener); 

    // build our dialog 
    AlertDialog.Builder builder = new AlertDialog.Builder(context); 

    // show prompt, just as our Spinner parent does 
    if (getPrompt() != null) { 
     builder.setTitle(getPrompt()); 
    } 

    // create and show dialog 
    myDialog = builder.setView(v).create(); 
    myDialog.show(); 

    return true; 
} 

@Override 
public void onItemClick(AdapterView<?> view, View itemView, int position, long id) { 
    setSelection(position); 
    if (myDialog != null) { 
     myDialog.dismiss(); 
     myDialog = null; 
    } 

} 

} を私はスピナーの各リスト項目のカスタム行を作成します。私は自分のアクティビティ内でcustomspinner.setadapter()を使ってCustomSpinnerにアダプタを設定できると思っていました。ただし、CustomSpinnerクラスで定義されたListViewは、クラス内で参照されるアダプタを使用します。アダプターをクラスに渡して使用できるようにするにはどうしたらいいですか?ここで

は、私は私のレイアウトにカスタム項目を追加しなければならなかった方法である:あなたが行うことができるかもしれない何

<com.bluelightuniverse.android.brewmobile.CustomSpinner 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/GrainNameSpinner" 
    android:layout_toRightOf="@id/GrainOriginSpinner" 
    android:layout_toLeftOf="@+id/AddGrainButton"> 
</com.bluelightuniverse.android.brewmobile.CustomSpinner> 

答えて

0

私はSpinnersのダイアログでより複雑なビューを作成することを実験してきました。

あなたが説明したように、私はSpinnerというサブクラスを作成しました。私は、Android Spinnerのsourceを調べて、performClickを上書きしました。本質的にあなたが望むことを行うには、自分のダイアログにカスタム表示を設定します。

package me.ribose.example; // you'll have to change this 

import android.app.AlertDialog; 
import android.content.Context; 
import android.database.DataSetObserver; 
import android.util.AttributeSet; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.Button; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.Spinner; 
import android.widget.SpinnerAdapter; 

public class CustomSpinner extends Spinner implements OnItemClickListener { 
    private AlertDialog mDialog = null; 
    private OnClickListener mButtonClickListener = null; 

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

    public void setButtonClickListener(OnClickListener listener) { 
     mButtonClickListener = listener; 
    } 

    @Override 
    public boolean performClick() { 
     Context context = getContext(); 

     // get the set adapter 
     final DropDownAdapter adapter = new DropDownAdapter(getAdapter()); 

     // inflate our layout 
     final LayoutInflater inflater = LayoutInflater.from(getContext()); 
     final View v = inflater.inflate(R.layout.customSpinner, null); 

     // set up list view 
     final ListView lv = (ListView) v.findViewById(R.id.list); 
     lv.setAdapter(adapter); 
     lv.setSelection(getSelectedItemPosition()); 
     lv.setOnItemClickListener(this); 

     // set up button 
     final Button btn = (Button) v.findViewById(R.id.addButton); 
     btn.setOnClickListener(mButtonClickListener); 

     // build our dialog 
     AlertDialog.Builder builder = new AlertDialog.Builder(context); 

     // show prompt, just as our Spinner parent does 
     if (getPrompt() != null) { 
      builder.setTitle(getPrompt()); 
     } 

     // create and show dialog 
     mDialog = builder.setView(v).create(); 
     mDialog.show(); 

     return true; 
    } 

    @Override 
    public void onItemClick(AdapterView<?> view, 
          View itemView, int position, long id) { 
     setSelection(position); 
     if (mDialog != null) { 
      mDialog.dismiss(); 
      mDialog = 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(); 
     } 

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

     @Override 
     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; 
     } 
    } 
} 

あなたは私のcustomSpinner.xml必要があります。もちろん、

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:orientation="vertical" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 
    <ListView 
      android:id="@+id/list" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:layout_weight="1" 
      android:layout_marginTop="5px" 
      android:cacheColorHint="@null" 
      android:background="@android:color/background_light" 
      android:divider="@android:drawable/divider_horizontal_bright" 
      android:scrollbars="vertical"> 
    </ListView> 
    <Button 
      android:id="@+id/addButton" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:text="Add to Database"> 
    </Button> 
</LinearLayout> 

は、android:text文字列リソースことを確認してください。この上

複数の単語:ちょうどあなたがそれを必要としてあなたの活動のレイアウトでCustomSpinnerを作ると、おそらく追加したり、何を促すことを、あなたのボタンのコールバックを追加する(おそらくあなたは、アダプタを設定する場所の近く)setButtonClickListenerを呼び出しますあなたが必要です。もちろんデータベースに追加した後は、notifyDataSetChanged()をアダプタにインストールしてください。スピナーで動作するすべてのものは、このカスタムスピナーとまったく同じように動作するはずです。

サイドノート(更新済み):アダプタのリストアイテムに黒いテキスト(例:android:textColor="@android:color/primary_text_light_nodisable")があることを確認する必要があります。上記のXMLを変更して、アイテムに白い背景を必要としないようにしました(アイテムのハイライトが機能しなくなりました)。


コードノート:アンドロイドを作った人たちは、ListAdapterSpinnerAdapter s「を変換」するsetSingleChoiceItems()だけでなく、プライベートクラスを使用して(AlertDialog.Builderのハードコードされた使用をスピナーダイアログをカスタマイズするための簡単な方法をしないことを決めたので、 s)、私は自分の内部クラス全体をコピーして、望ましい効果を得なければなりませんでした。また、彼らは悪い書類であることに注意してください(DropDownAdapterisEnabled/areAllItemsEnabled今日の笑いのために!)。あなたのCursorAdapterで

+0

あなたのコードは興味深い見えます、ありがとうございましたそれを説明する時間を費やすために。それは私のニーズに適しているかどうかを確認するために時間がかかります。だから私は理解しています...私はカスタムスピナーを作成しています。リストビューには通常どおりデータベース項目が含まれています。カスタム項目としてリストの一番下にあるボタンを使用していますか?私はリストの他の項目から目立つようにボタンの外観を変えることもできるはずだから、これが好きです。現在、カスタムSimpleCursorAdapterを使用してスピンを設定しています。私はDropDownAdapterとは対照的にそれを使い続けることはできますか? – ryandlf

+0

絶対に!必要なアダプタを使用し、カスタムのspinner.setAdapter(yourAdapter)に渡します。 DropDownAdapterプライベートクラスは、Androidソースコードが現在行っているのとまったく同じように、SpinnerAdapter - > ListAdapterを作成するだけです。 Spinner.setAdapter()を渡すことができますので、これを渡すことができます。 – Ribose

+0

あなたはDropDownAdapterを直接使用していません。このサブクラスは、基本的に変更を必要としないことを意図しています(ただし、レイアウトを変更してクリックハンドラを追加することで、ボタンの数を増やすなど)。 [アンドロイドのソースコード](http://www.netmite.com/android/mydroid/frameworks/base/core/java/android/widget/Spinner.java)を参照して、正確なコピーを参照してハードを回避してくださいカスタマイズ可能なスピナー。 – Ribose

0

MergeAdapterを使用している:これはあなたのデータベースアダプタを取り込んで、アダプタを作成することができますし、静的なビュー(アイテムをデータベースに追加するボタン)をクリックし、Spinnerビューとして設定します。私はListViewのためにこれを使用しましたが、Spinnerのためには使用しませんでしたので、それがうまくいくかどうかは不確かですが、私はそうするでしょう。

7

、メソッド同様にgetCount()とgetDropDownViewオーバーライド:例では を使用すると、最後にボタンを置きたい場合は、あなたがこれを行うことができます:

new SimpleCursorAdapter(...) { 

     @Override 
     public int getCount() { 
      return super.getCount()+1; 
     } 

     @Override 
     public View getDropDownView(int position, View convertView, 
       ViewGroup parent) { 
      View res=null; 
      if (position == getCount()-1) { 
       //better not try to reuse our view as it can be requested for the spinner or by the list with different kind of layouts. 
       View mButton= getActivity().getLayoutInflater().inflate(R.layout.create_activity_button, parent,false); 
       mButton.setOnClickListener(ObservationListFragment.this); 
       res= mButton; 
      } else if (convertView != null && android.R.id.button1 == convertView.getId()){ 
      // If the adapter is trying to recycle our footer view, we force the generation of a new view (check on the id of our custom view) 
       res= super.getDropDownView(position, null, parent); 
      } else { 
       res= super.getDropDownView(position, convertView, parent); 
      } 
      return res; 
     } 
    }; 
+0

これをCursorAdapter(SimpleCursorAdapterではなく)を使用して実行すると、存在しない位置にカーソルを移動しようとしているのでエラーが発生します。なにか提案を? – AdamMc331