java - 如何在 RecyclerView 中修改 Layout 宽度

标签 java android android-recyclerview

我正在努力使用 RecyclerView 和具有一些监听器的布局。

代码是这样的

  • ViewHolder

     public static class ViewHolder extends RecyclerView.ViewHolder {
    
        public TextView tickerSymbol;
        public TextView companyName;
        public View highlightBuy;
        public LinearLayout categoryImage;
        public LayoutParams categoryLayoutParams;
        public LinearLayout arrowImage;
        public ImageView categoryIconSeparator;
        public ImageView arrowSeparator;
        public ImageView arrowIcon;
        public RelativeLayout stockRow;
        public LinearLayout tickerInfo;
        public Boolean isCategoryOpened = false;
    
        public ViewHolder(View itemView) {
            super(itemView);
            this.tickerSymbol = (TextView) itemView.findViewById(R.id.ticker_symbol_textview);
            this.companyName = (TextView) itemView.findViewById(R.id.company_name_textview);
            this.highlightBuy = itemView.findViewById(R.id.highlight_buy_view);
            this.categoryImage = (LinearLayout) itemView.findViewById(R.id.category_image);
            this.categoryLayoutParams = (LayoutParams) categoryImage.getLayoutParams();
            this.arrowImage = (LinearLayout) itemView.findViewById(R.id.arrow);
            this.categoryIconSeparator = (ImageView) itemView.findViewById(R.id.category_icon_separator);
            this.arrowSeparator = (ImageView) itemView.findViewById(R.id.arrow_separator);
            this.arrowIcon = (ImageView) itemView.findViewById(R.id.arrow_icon_imageview);
            this.stockRow = (RelativeLayout) itemView.findViewById(R.id.stock_row);
            this.tickerInfo = (LinearLayout) itemView.findViewById(R.id.ticker_info);
        }
    }
    
  • onCreateViewHolder

    @Override
    public StockListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
      Context context = parent.getContext();
      LayoutInflater inflater = LayoutInflater.from(context);
    
      View stockView = inflater.inflate(R.layout.stock_list_row, parent, false);
    
      return new StockListAdapter.ViewHolder(stockView);
    }
    
  • onBindViewHolder

    @Override
    public void onBindViewHolder(final StockListAdapter.ViewHolder holder, final int position) {
      final Stock stock = mStocks.get(position);
      final int collapsedCategoryWidth = (int) mContext.getResources().getDimension(R.dimen.collapsed_category_icon_width);
      final int stockRowHeight = (int) mContext.getResources().getDimension(R.dimen.stock_row_height);
    
      //Reset holder status
      if (holder.isCategoryOpened) {
          holder.isCategoryOpened = false;
          holder.categoryImage.getLayoutParams().width = collapsedCategoryWidth;
          holder.categoryImage.setLayoutParams(holder.categoryImage.getLayoutParams());
          holder.arrowIcon.setRotationY(0);
      }
    
      holder.tickerSymbol.setText(stock.ticker);
    
      holder.companyName.setText(stock.name);
      holder.companyName.setSelected(true);
      holder.companyName.requestFocus();
    
      holder.categoryImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
    
            final int newWidth;
            final int startWidth;
            final int startArrowAngle;
            final int newArrowAngle;
    
            if (!holder.isCategoryOpened) {
                holder.isCategoryOpened = true;
                newWidth = holder.stockRow.getWidth() - holder.categoryLayoutParams.leftMargin - holder.arrowImage.getWidth() - ((LayoutParams) holder.arrowImage.getLayoutParams()).rightMargin - holder.categoryIconSeparator.getWidth();
                startWidth = collapsedCategoryWidth;
                startArrowAngle = 0;
                newArrowAngle = 180;
            } else {
                holder.isCategoryOpened = false;
                newWidth = collapsedCategoryWidth;
                startWidth = holder.categoryImage.getWidth();
                startArrowAngle = 180;
                newArrowAngle = 0;
            }
    
            Animation a = new Animation() {
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    holder.categoryLayoutParams.width = startWidth + (int) ((newWidth - startWidth) * interpolatedTime);
                    //MAYBE PROBLEM HERE??
                    holder.categoryImage.setLayoutParams(holder.categoryLayoutParams);
                    holder.arrowIcon.setRotationY(startArrowAngle + (newArrowAngle - startArrowAngle) * interpolatedTime);
                }
            };
            a.setDuration(500);
            holder.categoryImage.startAnimation(a);
        }
    });
    

我将附上我遇到的错误示例。

Bug Part One

当我第一次单击 View 时,onClick 成功运行,但如果我滚动然后返回到该 View ,则只有箭头翻转(这意味着 onClick 被调用)但 LinearLayout Width 不会被修改。

但现在真正奇怪的是,如果我点击另一个以前没有被点击过,或者(我猜)没有被回收的 View ,会发生以下情况:

Bug Part Two

所以我猜,宽度已设置,但未显示。

我真的不知道如何解决这个问题。

感谢您的帮助或其他想法!

这是我已经尝试过的:

  • 将状态放入库存;
  • 将监听器置于适配器之外;
  • 将监听器放入支架内;

最佳答案

如果您是否已经点击该项目,请在您的商店类中将 1 个变量添加到存储值中..

像这样的插图,我在商店中设置了变量 isSelected :

 private boolean mSelected=false;

 public boolean getIsSelected(){
        return this.mSelected;
    }
    public void setIsSelected(boolean mSelected){
        this.mSelected=mSelected;
    }

然后在您的 onClick 方法中,只需在 if 条件之后添加 stock.setIsSelected(!stock.getIsSelected()) 并将您的 if 条件设置为从 stock.getIsSelected()< 读取 boolean 值 最后,只需从您的 holder 中删除变量 isCategoryOpened。

public void onClick(View v) {

        final int newWidth;
        final int startWidth;
        final int startArrowAngle;
        final int newArrowAngle;

        if (stock.getIsSelected()) {
            newWidth = holder.stockRow.getWidth() - holder.categoryLayoutParams.leftMargin - holder.arrowImage.getWidth() - ((LayoutParams) holder.arrowImage.getLayoutParams()).rightMargin - holder.categoryIconSeparator.getWidth();
            startWidth = collapsedCategoryWidth;
            startArrowAngle = 0;
            newArrowAngle = 180;
        } else {
            newWidth = collapsedCategoryWidth;
            startWidth = holder.categoryImage.getWidth();
            startArrowAngle = 180;
            newArrowAngle = 0;
        }
       stock.setIsSelected(!stock.getIsSelected())
        Animation a = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                holder.categoryLayoutParams.width = startWidth + (int) ((newWidth - startWidth) * interpolatedTime);
                //MAYBE PROBLEM HERE??
                holder.categoryImage.setLayoutParams(holder.categoryLayoutParams);
                holder.arrowIcon.setRotationY(startArrowAngle + (newArrowAngle - startArrowAngle) * interpolatedTime);
            }
        };
        a.setDuration(500);
        holder.categoryImage.startAnimation(a);
    }

如果我错了请纠正我:)

关于java - 如何在 RecyclerView 中修改 Layout 宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36644764/

相关文章:

Android Studio 导入 Google Play Services 项目刷新失败

android - 尝试运行我的 Espresso 测试时 RecyclerViewMatcher 出现 NullPointerException

android - LinearLayoutManager 无法解析 getOrientation()

java - 使用 Twitter4j 发布 Twitter 线程

java - 如何使用 gradle 在构建时复制资源以进行测试

java - 列出每次占用 9 个单元格的 9x9 框的所有可能组合

android - Robotium Activity 泄漏导致其他测试的错误 Activity

java - 使用 restAssured 测试 Spring Boot Rest 应用程序

android - 按下 imageView 时更改 imageView 中的资源的问题

android - fragment 没有膨胀