【问题标题】:Actionbar list navigation width - wrap content操作栏列表导航宽度 - 换行内容
【发布时间】:2013-01-20 16:26:03
【问题描述】:

默认情况下,在操作栏列表中,所选项目的导航宽度与最宽项目一样宽。我想在所选项目中“包装内容”,因为它在 google+、gmail、maps android 应用程序中。

有人知道很热吗?

我试图覆盖导航适配器的 getView 但它不起作用。看起来这个视图被另一个具有最宽项目宽度的视图包裹着。我还尝试了带有微调器的 actionbar.setCustom 视图,但微调器的行为是相同的。它使用最宽的项目宽度。

感谢所有建议、链接和帮助。

【问题讨论】:

    标签: android android-layout android-actionbar


    【解决方案1】:

    我遇到了同样的问题。看来Android会为所有的item调用getView()方法,最后把width设置为最宽的item的宽度。

    所以这是我的解决方案:

    1. 在代码中存储当前选定的部分(例如,示例中的部分),例如 selectedSection。实际上你必须在 NavigationListener 的 onNavigationItemSelected() 方法中进行。

    2. 覆盖 SpinnerAdapter 的 getView() 方法,始终将其内容设置为 selectedSection。

    3. 在 NavigationListener 的 onNavigationItemSelected() 方法中,将当前模式设置为 selectedSection 后,尝试调用 spinnerAdapter 的 notifyDataSetChanged() 方法。

    示例代码如下:

    final int selectedSection = 0;
    final String sectionLabels[] = {"short sec", "long section", "looooonger section"};
    
    final ArrayAdapter<String> arrayAdapter =
      new arrayAdapter<String>(this, simple_list_item_1) {
        @Override
        public int getCount() {
          // You need to implement here.
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
          if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.you_entry, null);
          }
          TextView textView = (TextView) convertView.findViewById(R.id.you_text);
          // Set the text to the current section.
          textView.setText(sectionLabels[selectedSection]);
        }
    
        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
          // You need to implement here.
        }
    
      }
    
    actionBar.setListNavigationCallbacks(navigationAdpater,
      new ActionBar.OnNavigationListener() {
    
        @Override
        public boolean onNavigationItemSelected(int itemPosition, long itemId) {
          // Store the current section.
          selectedSection = itemPosition;
          navigationAdpater.notifyDataSetChanged();
          return true;
        }
      });
    

    【讨论】:

    • 很好的答案!!!谢谢你。您也可以替换 textView.setText(sectionLabels[selectedSection]);与 textView.setText(sectionLabels[actionBar.getSelectedNavigationIndex()]);所以你不需要 selectedSection
    • 啊,是的!我们不需要 selectedSection ;-) @vandzi
    • 还有更简单的方法。在 getView() 调用 ((AdapterView) parent).getSelectedItemPosition() 获取当前位置。
    【解决方案2】:

    您需要覆盖适配器中的 getView() 方法并将布局参数设置到 textview 以包装内容。微调器将自动调整所选项目的大小。

    我创建了一个从 ArrayAdapter 扩展的自定义适配器:

    public class CustomAdapter extends ArrayAdapter<String> {
    

    之后我重写了改变当前视图的 LayoutParams 的 getView() 方法:

    @Override 
    public View getView(final int position, final View convertView, final ViewGroup parent) {
                View view = convertView;
                if (null == view) {
                    view = LayoutInflater.from(this.getContext())
                             .inflate(android.R.layout.simple_list_item1, null);
                    ((TextView) view).setText(getItem(position));
                }
                final LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
                                                   LayoutParams.WRAP_CONTENT);
                view.setLayoutParams(params);
                return view;
    }
    

    在您的活动中,创建适配器实例并使用它设置您的微调器:

    List<String> stringList = new ArrayList<String>();
    stringList.add("test1");
    stringList.add("test12");
    stringList.add("test123");
    stringList.add("test1234");
    
    final SpinnerAdapter adapter = new CustomAdapter(this.getContext(),
                                                     android.R.layout.simple_list_item1,
                                                     android.R.id.text1, 
                                                     stringList);
    mySpinner.setAdapter(adapter);
    

    当您在列表中选择某些内容时,微调器将重新创建视图,将所选项目重新排序到第一个位置,并将其自身调整为内容的大小。

    【讨论】:

      【解决方案3】:

      创建一个微调器并向其中添加文本视图。在微调器上,将 maxWidth 字段设置为您想要的任何值,这样就可以处理这个问题。另一种选择是设置

      android:layout_width="0"
      android_layout_weight="0.3"
      

      这意味着微调器将只占据屏幕宽度的 1/3。

      在你要设置的文本视图上:

      android:singleLine="false"
      android:ellipsize="end"
      

      【讨论】:

      • 谢谢。不幸的是,它不起作用。我知道如何设置固定宽度。但我想将微调器宽度设置为选定项目的宽度。
      • 然后您可以执行 OnGlobalLayoutChangeListener 并将微调器宽度设置为选定项的宽度。
      【解决方案4】:

      这对我有用。重要的部分是这个。把上面的代码放在你的适配器上,并使用 selectedItemPosition 从对象数组中选择文本。

      int selectedItemPosition = position;
          if (parent instanceof AdapterView) {
              selectedItemPosition = ((AdapterView) parent)
                      .getSelectedItemPosition();
          }
      

      示例如下。

      public View getView(int position, View convertView, ViewGroup parent) {
          LayoutInflater inflater = getLayoutInflater();
          final View spinnerCell;
          if (convertView == null) {
              // if it's not recycled, inflate it from layout
              spinnerCell = inflater.inflate(R.layout.layout_spinner_cell, parent, false);
          } else {
              spinnerCell = convertView;
          }
          int selectedItemPosition = position;
          if (parent instanceof AdapterView) {
              selectedItemPosition = ((AdapterView) parent)
                      .getSelectedItemPosition();
          }
      
          TextView title = (TextView) spinnerCell.findViewById(R.id.spinnerTitle);
          title.setText(titles[selectedItemPosition]);
          return spinnerCell;
      }
      

      如果您需要解释,请点击此链接:http://coding-thoughts.blogspot.in/2013/11/help-my-spinner-is-too-wide.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多