微调器下拉外边框

Spinner dropdown outer border

如何为整个下拉列表而不是项目本身设置边框?

预期:

可能看不清楚,但我对整个下拉菜单外的白色边框很感兴趣。见红字

现实:

spinner_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/primary_blue_dark">

    <TextView
        android:id="@+id/tv_spinner_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="12dp"
        android:gravity="center_vertical|start"
        style="@style/sp_squared_style"/>

    <ImageView
        android:id="@+id/iv_underline"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_marginBottom="6dp"
        android:background="@drawable/ic_underline"/>
</LinearLayout>

Drawable文件夹下新建一个border.xml文件,写入如下代码

<?xml version="1.0" encoding="utf-8"?>

<item>
    <shape android:shape="rectangle" >
        <solid android:color="@color/edittext_line_color" />
    </shape>
</item>
<item
    android:bottom="1dp"
    android:left="1dp"
    android:right="1dp"
    android:top="1dp">
    <shape android:shape="rectangle" >
        <solid android:color="@color/app_screen_back_color" />
    </shape>
</item>

之后将背景设置为 Spinner 之类的,

android:background="@drawable/border.xml"

希望对您有所帮助...:)

您需要在 drawable 文件夹中创建一个单独的 XML 文件

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white_overlay_8x" />
    <corners android:radius="6dip" />
    <stroke
        android:color="@color/white"
        android:width="@dimen/dot" />

</shape>

并设置

android:background=@drawable/file;

在你的 spinner_item.xml:

找到解决方法。不确定,也许有更好的解决方案。无论如何:

1) spinner_item.xml - 在布局中包装内容

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey_stroke" //add white border
>

<LinearLayout
    android:id="@+id/ll_wrapper"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="1dp" //set margin left and right
    android:layout_marginRight="1dp" //add bottom and top margins dynamically in adapter
    android:orientation="vertical"
    android:background="@color/primary_blue_dark">
    <TextView
        android:id="@+id/tv_spinner_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/activity_vertical_margin_small"
        android:gravity="center_vertical|start"
        style="@style/sp_squared_style"/>

    <ImageView
        android:id="@+id/iv_underline"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="@dimen/activity_vertical_margin_small"
        android:layout_marginLeft="@dimen/activity_vertical_margin_small"
        android:layout_marginBottom="6dp"
        android:background="@drawable/ic_underline"/>
</LinearLayout>

2) 为第一个元素和适配器中的底部元素添加边距底部:

public class AmountAdapter extends ArrayAdapter<String> {

private TextView tvRow;
private TextView tvItem;
private LinearLayout llWrapper;
private Context context;
private ImageView ivUnderline;
private String[] values;

private int border;


public AmountAdapter(Context context, int textViewResourceId,
                         String[] values) {
    super(context, textViewResourceId, values);
    this.context = context;
    this.values = values;
    border = (int) context.getResources().getDimension(R.dimen.rounding_radius_dp_1);
}

public int getCount() {
    return values.length;
}

public String getItem(int position) {
    return values[position];
}

public String[] getItems() {
    return values;
}


public long getItemId(int position) {
    return position;
}

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

    LayoutInflater inflater = LayoutInflater.from(context);
    View row;

    row = inflater.inflate(R.layout.item_spinner_row, parent, false);
    tvRow = (TextView) row.findViewById(R.id.tv_spinner_row);
    return row;
}

@Override
public View getDropDownView(final int position, View convertView,
                            ViewGroup parent) {
    View row;

    row = View.inflate(context, R.layout.item_spinner_dropdown, null);
    llWrapper = (LinearLayout) row.findViewById(R.id.ll_wrapper);
    tvItem = (TextView) row.findViewById(R.id.tv_spinner_item);
    tvItem.setText(values[position]);

    ivUnderline = (ImageView) row.findViewById(R.id.iv_underline);

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
    );


    if (position == values.length - 1){
        ivUnderline.setVisibility(View.GONE);
        int padding = (int)context.getResources().getDimension(R.dimen.activity_vertical_margin_small);
        int paddingTop = (int)context.getResources().getDimension(R.dimen.rounding_radius_dp);
        tvItem.setPadding(padding, paddingTop, 0, padding);

        params.setMargins(border, 0, border, border); //end part
        llWrapper.setLayoutParams(params);
    } else if(position == 0){
        params.setMargins(border, border, border, 0); //start part
        llWrapper.setLayoutParams(params);
    } else {
        params.setMargins(border, 0, border, 0); //middle part
        llWrapper.setLayoutParams(params);
    }

    return row;
}
}

3) 结果:

多亏了 Ben-J 评论和 回答,我使用此代码使用 ThemeOverlay.AppCompat.Light 子样式创建了边框。

这将为外部列表覆盖创建填充,这将显示底层覆盖背景。您还需要为列表项设置一个明确的背景,这样它们就不会透明。

layout/main_layout.xml:

<Spinner xmlns:app="http://schemas.android.com/apk/res-auto"
  app:popupTheme="@style/LangList_SpinnerPopupOverlay" />

values/styles.xml:

<style name="LangList_SpinnerPopupOverlay" parent="ThemeOverlay.AppCompat.Light">
  <!-- border width -->
  <item name="android:padding">1dp</item>
  <!-- border color -->
  <item name="android:background">#f00</item>
</style>

layout/spinner_list_item.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <TextView
    android:id="@+id/itemText"
    android:background="#fff"/>
</LinearLayout>

layout/spinner_view.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <TextView
    android:id="@+id/itemText"/>
</LinearLayout>

CustomListAdapter.java:

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CustomListAdapter extends ArrayAdapter<CustomListItem> {

  private Context context;

  public CustomListAdapter(Context context, List<CustomListItem> items) {
    super(context, R.layout.spinner_list_item, items);
    this.context = context;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    // spinner layout (when closed)
    int layoutId = R.layout.spinner_view;
    return createView(position, convertView, parent, layoutId);
  }

  @Override
  public View getDropDownView(int position, View convertView, ViewGroup parent) {
    // dropdown list layout
    int layoutId = R.layout.spinner_list_item;
    return createView(position, convertView, parent, layoutId);
  }

  private View createView(int position, View convertView, ViewGroup parent, int layoutId) {
    if (convertView == null) {
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      convertView = inflater.inflate(layoutId, null);
    }

    TextView itemText = convertView.findViewById(R.id.itemText);

    CustomListItem item = getItem(position);
    if (item != null) {
      itemText.setText(item.getText());
    }

    return convertView;
  }

}

因为这个花了我很多时间才找到,希望它能帮助别人...

首先在 drawable 文件夹中创建一个带有所需边框的新 spinner_dropdown_border.xml:

  <?xml version="1.0" encoding="UTF-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <solid android:color="@color/basic_color"/>
        <stroke
            android:width="2dp"
            android:color= "@color/border_color"/>
    </shape>

然后像这样将此边框应用到微调器:

   <Spinner
        android:id="@+id/spinner"
        android:layout_width="0dp"
        android:layout_height="50dp"
        ...
        android:spinnerMode="dropdown"
        android:popupBackground="@drawable/spinner_dropdown_border" />

这将只对边框起作用,而不是对下拉列表的每个项目单独起作用:

android:popupBackground="@drawable/spinner_dropdown_border"

Spinner border image