有没有办法在微调器下拉列表中添加页脚?例如,假设我正在从数据库中填充一个微调器,但我想在列表的底部进行选择,而不管我如何安排列表。列表可能是“Database Item 1,2 ...,3 ...”,并在列表底部选择“Add Item to Database”。
到目前为止,我已经使用了您的CustomSpinner类,如下所示:
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;
}
}
} 我想使用一个单独的适配器,如:
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;
}
}
这允许我为微调器中的每个listitem构建一个自定义行。我想我可以使用我的活动中的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 :(得分:8)
在CursorAdapter中,覆盖方法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;
}
};
答案 1 :(得分:0)
您可以使用MergeAdapter:这可以让您创建一个接收数据库适配器的适配器和一个静态视图(将项添加到数据库的按钮)并将其设置为Spinner视图。我已将此用于ListView
s但不用于Spinner
s,因此不确定它是否会起作用,但我认为它会。
答案 2 :(得分: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()
。在Spinner上工作的所有东西都应该与这个自定义微调器完全相同。
旁注(更新):您必须确保适配器的列表项具有黑色文本(例如:android:textColor="@android:color/primary_text_light_nodisable"
)!我更改了上面的XML,因此它不需要项目的白色背景(然后使项目高亮不起作用)。
代码注释:由于制作Android的人决定不轻松自定义微调器对话框(使用AlertDialog.Builder
使用setSingleChoiceItems()
进行硬编码以及使用“转换”私有类SpinnerAdapter
到ListAdapter
s),我必须复制他们的整个内部类以获得所需的效果。另请注意,他们是糟糕的记录员(请参阅DropDownAdapter
。isEnabled
/ areAllItemsEnabled
了解当天的笑声!)。