在Android操作栏中下拉搜索栏?

时间:2013-07-01 15:07:47

标签: android android-actionbar seekbar

我正在尝试在操作栏中放置一个下拉/下拉搜索栏。我认为OnCreateOptionsMenu()中的这样的东西会起作用:

    SubMenu subMenu = menu.addSubMenu("DropTest");

    MenuItem seekBarDrop = subMenu2.add("SeekBar");
    SeekBar seekBar = new SeekBar(this);
    seekBarDrop.setActionView(seekBar);
    seekBarDrop.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

    MenuItem subMenuItem = subMenu2.getItem();
    subMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

但它失败了。我也试过将它黑客入到一个微调器适配器中(使用IcsSpinner for actionbarsherlock):

    ArrayAdapter<CharSequence> seekAdapter = 
            new ArrayAdapter<CharSequence>(context,
            R.layout.spinner_subtitled_octave, 
            android.R.id.text1, new String[]{""});

    seekAdapter.setDropDownViewResource(R.layout.seekbar);

    MenuItem itemX = menu.add("SeekBar").setActionView(R.layout.spinner_ics);
    itemX.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

    IcsSpinner spinBar = (IcsSpinner) itemX.getActionView();
    spinBar.setAdapter(seekAdapter);

    /*
     * This next part doesn't crash, but it also doesn't work
     */

    LinearLayout sbLayout = (LinearLayout)
            seekAdapter.getDropDownView(0, null, null);

    SeekBar seekBar = (SeekBar) sbLayout.findViewById(R.id.v_seekbar);
    seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            Log.d(TAG, "" + progress); // nope
        }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {  }
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {  }
    });

使用seekbar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView 
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/highlight"
/>
<SeekBar
android:id="@+id/v_seekbar"
android:minWidth="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/spacer" />

</LinearLayout>

和spinner_seek.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:id="@+id/TextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SEEKBAR"
android:padding="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/main" />

<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/highlight" />

</LinearLayout>

它至少会获得一个搜索栏下拉列表,但我无法弄清楚如何获取它。

有人知道怎么去最后一英里吗?

编辑:写完之后我注意到PopupMenu存在,但它只有API 11+(我的项目是10+)或HoloEverywhere。希望在没有ABS之外的任何库的情况下这样做。

2 个答案:

答案 0 :(得分:5)

这是你在找什么: enter image description here

我是通过使用BaseAdapter来实现的:

MainActivity:

public class MainActivity extends Activity implements OnNavigationListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ActionBar bar = getActionBar();
    ArrayList<String> list = new ArrayList<String>();
    list.add("bar 0 ");
    list.add("bar 2 ");
    list.add("bar 3 ");
    list.add("bar 4 ");
    Adapter adapter = new Adapter();

    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    bar.setListNavigationCallbacks(adapter.getAdapter(this, list, "Controls"), this);
    adapter.setSeekBarListener( new SeekBarListener(){

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser, int positionInList) {
            Log.i("", "onProgressChanged " + progress + " position in list" + positionInList);

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar, int positionInList) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar, int positionInList) {
            // TODO Auto-generated method stub

        }

    });
}


@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
    // TODO Auto-generated method stub
    return false;
}

}

Adapter.class:

public class Adapter {
private SeekBarListener mListener;

public interface SeekBarListener{
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser, int positionInList);
    public void onStartTrackingTouch(SeekBar seekBar, int positionInList);
    public void onStopTrackingTouch(SeekBar seekBar, int positionInList);
}

public listAdapter getAdapter(Context context, ArrayList<String> list, String title){
    return new listAdapter(context, list, title);
}

public void setSeekBarListener(SeekBarListener listener){
    mListener = listener;
}

public class listAdapter extends BaseAdapter {
    private LayoutInflater mInflater;
    private onSeekbarChange mSeekListener;
    private ArrayList<String> itemsList;
    private String title;

    public listAdapter(Context context, ArrayList<String> list, String title){
        mInflater = LayoutInflater.from(context);
        if(mSeekListener == null){
            mSeekListener = new onSeekbarChange();
        }
        this.itemsList = list;
        this.title = title;
    }

    @Override
    public int getCount() {
        return itemsList.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder2 holder;

        if(convertView == null){
            holder = new ViewHolder2();
            convertView = mInflater.inflate(R.layout.baseadapter_layout, null);
            holder.text_title = (TextView)convertView.findViewById(R.id.textView);
            convertView.setTag(R.layout.baseadapter_layout, holder);
        } else {
            holder = (ViewHolder2)convertView.getTag(R.layout.baseadapter_layout);
        }
        holder.text_title.setText(title);
        return convertView;
    }


    @Override 
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        if(convertView == null){
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.baseadapter_dropdown_layout, null);
            holder.text = (TextView)convertView.findViewById(R.id.textView1);
            holder.seekbar = (SeekBar)convertView.findViewById(R.id.seekBar1);
            convertView.setTag(R.layout.baseadapter_dropdown_layout, holder);
        } else {
            holder = (ViewHolder)convertView.getTag(R.layout.baseadapter_dropdown_layout);
        }
        holder.text.setText(itemsList.get(position));
        holder.seekbar.setOnSeekBarChangeListener(mSeekListener);
        holder.seekbar.setTag(position);
        return convertView;

    }

}

static class ViewHolder {
    TextView text;
    SeekBar seekbar;
}

static class ViewHolder2 {
    TextView text_title;
}


public class onSeekbarChange implements OnSeekBarChangeListener{

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        int position = (Integer) seekBar.getTag();
        if(mListener != null){
            mListener.onProgressChanged(seekBar, progress, fromUser, position);
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        int position = (Integer) seekBar.getTag();
        if(mListener != null){
            mListener.onStartTrackingTouch(seekBar, position);
        }
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int position = (Integer) seekBar.getTag();
        if(mListener != null){
            mListener.onStopTrackingTouch(seekBar, position);
        }
    }

}

}

baseadapter_layout.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="25dp"
    android:layout_marginTop="18dp"
    android:textColor="#FFFFFF"
    android:text="Controls" />

baseadapter_dropdown_layout.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="15dp"
    android:layout_marginTop="15dp"
    android:textColor="#FFFFFF"
    android:text="TextView" />

<SeekBar
    android:id="@+id/seekBar1"
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="11dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_toRightOf="@+id/textView1" />

答案 1 :(得分:3)

这有点复杂,但您可以创建自己的PopupWindow来显示下拉列表SeekBar

以下内容适用于所有标准的Holo主题。

的活动:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    String title = "Seek Bar Test";
    SeekBar seekBar = addDropDownSeekBar(this, menu, title);

    return true;
}

private SeekBar addDropDownSeekBar(Context context, Menu menu, String title) {
    LayoutInflater inflater = LayoutInflater.from(context);

    View contentView = inflater.inflate(R.layout.drop_down_seek_bar, null);
    SeekBar seekBar = (SeekBar) contentView.findViewById(R.id.drop_down_seek_bar);

    final PopupWindow popupWindow = new PopupWindow(context, null,
            android.R.attr.actionDropDownStyle);
    popupWindow.setFocusable(true); // seems to take care of dismissing on click outside
    popupWindow.setContentView(contentView);
    setPopupSize(popupWindow);

    final int paddingTop = getPaddingTop(popupWindow);

    MenuItem menuItem = menu.add("");
    FrameLayout button = createActionButton(context, title);
    menuItem.setActionView(button);
    menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);

    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // compensate for PopupWindow's internal padding
            popupWindow.showAsDropDown(v, 0, -paddingTop);
        }
    });

    return seekBar;
}

private FrameLayout createActionButton(Context context, String title) {
    FrameLayout frame = new FrameLayout(context, null, android.R.attr.actionButtonStyle);
    frame.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
            LayoutParams.MATCH_PARENT));
    TextView text = new TextView(context, null, android.R.attr.actionMenuTextAppearance);
    text.setGravity(Gravity.CENTER_VERTICAL);
    text.setText(title);
    frame.addView(text);
    return frame;
}

private void setPopupSize(PopupWindow popupWindow) {
    View contentView = popupWindow.getContentView();

    int unspecified = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    contentView.measure(unspecified, unspecified);

    int width = contentView.getMeasuredWidth();
    int height = contentView.getMeasuredHeight();

    Drawable background = popupWindow.getBackground();
    if (background != null) {
        Rect rect = new Rect();
        background.getPadding(rect);
        width += rect.left + rect.right;
        height += rect.top + rect.bottom;
    }

    popupWindow.setWidth(width);
    popupWindow.setHeight(height);
}

private int getPaddingTop(PopupWindow popupWindow) {
    Drawable background = popupWindow.getBackground();
    if (background == null)
        return 0;

    Rect padding = new Rect();
    background.getPadding(padding);
    return padding.top;
}

布局文件drop_down_seek_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <SeekBar
        android:id="@+id/drop_down_seek_bar"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical" />

</FrameLayout>