繁体   English   中英

单击功能未按预期运行; 为什么? (Android Studio, RecyclerView)

[英]On Click function not behaving as expected; confused as to why? (Android Studio, RecyclerView)

好吧,我整个周末都在思考这个问题,我绕着圈子跑,把自己弄糊涂了; 所以有人请帮忙。 这是独家新闻:我有一个带有 RecyclerView 的应用程序来保存 CardView 项目。 这是布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardCornerRadius="4dp"
    app:cardBackgroundColor="#75757A">

    <RelativeLayout
        android:id="@+id/listItemWrapper"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="4dp">

        <TextView
            android:id="@+id/assetSymbol"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="SYM"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            android:textStyle="bold">
        </TextView>

        <TextView
            android:id="@+id/assetPrice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:layout_toEndOf="@+id/assetSymbol"
            android:text="$1,000.00"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            android:textStyle="bold"
            android:layout_toRightOf="@+id/assetSymbol">
        </TextView>

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="30sp"
            android:layout_height="30sp"
            android:layout_margin="8dp"
            android:layout_toEndOf="@+id/assetPrice"
            android:padding="2dp"
            android:layout_toRightOf="@+id/assetPrice">
        </ImageView>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/openShort"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/assetPrice"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:backgroundTint="@color/bearRed"
            android:clickable="true"
            android:visibility="gone"
            app:fabSize="mini"
            app:srcCompat="@drawable/ic_bear_enter" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/openLong"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/assetPrice"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:layout_toStartOf="@+id/openShort"
            android:layout_toLeftOf="@+id/openShort"
            android:backgroundTint="@color/bullGreen"
            android:clickable="true"
            android:visibility="gone"
            app:fabSize="mini"
            app:srcCompat="@drawable/ic_bull_enter" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/deleteAsset"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/assetPrice"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:layout_toStartOf="@+id/openLong"
            android:layout_toLeftOf="@+id/openLong"
            android:backgroundTint="@color/colorPrimary"
            android:clickable="true"
            android:visibility="gone"
            app:fabSize="mini"
            app:srcCompat="@drawable/ic_delete_asset" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/editAsset"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/assetPrice"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:layout_toStartOf="@+id/deleteAsset"
            android:layout_toLeftOf="@+id/deleteAsset"
            android:backgroundTint="@color/colorPrimary"
            android:clickable="true"
            android:visibility="gone"
            app:fabSize="mini"
            app:srcCompat="@drawable/ic_edit_asset" />

    </RelativeLayout>

    <ImageView
        android:id="@+id/showOptions"
        android:layout_width="wrap_content"
        android:layout_height="32dp"
        android:layout_gravity="end"
        android:layout_margin="8dp"
        app:srcCompat="@drawable/ic_baseline_more_vert" />

</androidx.cardview.widget.CardView>

您会注意到卡片包含四个浮动操作按钮,它们最初是隐藏的。 我想要做的是当用户单击“显示选项”ImageView(android:id="@+id/showOptions")时让按钮动画进入视图。 这是所有相关的代码片段:

主活动.java

public class MainActivity extends AppCompatActivity implements OnClickListener {

    private ArrayList<WatchListItem> watchListArray;
    private RecyclerView watchList;
    private WatchListAdapter listAdapter;
    private RecyclerView.LayoutManager listManager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        watchListArray = new ArrayList<>();
        watchList = (RecyclerView) findViewById(R.id.watchList);
        watchList.setHasFixedSize(true);
        listManager = new LinearLayoutManager(this);
        watchList.setLayoutManager(listManager);
        listAdapter = new WatchListAdapter(watchListArray);
        watchList.setAdapter(listAdapter);
    }

    public void engage(Asset asset) {
        int position = watchListArray.size();
        String ticker = asset.getSymbol();
        //Double.toString(asset.getCurrentPrice()) replaced with fixed value for testing
        String price = "390.55";
        //int indicator set to fixed value for testing
        int indicator = R.drawable.ic_bull_indicator;
        watchListArray.add(position, new WatchListItem(indicator, price, ticker));
        listAdapter.notifyItemInserted(position);
        listAdapter.setOnItemClickListener(new WatchListAdapter.OnItemClickListener() {
            @Override
            public void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
                expandListItem(position, show, edit, delete, oLong, oShort);
            }
        });
    }

    public void expandListItem(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
        if (edit.getVisibility() == View.GONE) {
            show.setImageResource(R.drawable.ic_collapse);
            oShort.animate().alpha(1f).setDuration(150);
            oLong.animate().alpha(1f).setStartDelay(125).setDuration(150);
            delete.animate().alpha(1f).setStartDelay(250).setDuration(150);
            edit.animate().alpha(1f).setStartDelay(375).setDuration(150);
        } else {
            edit.animate().alpha(0f).setDuration(150);
            delete.animate().alpha(0f).setStartDelay(125).setDuration(150);
            oLong.animate().alpha(0f).setStartDelay(250).setDuration(150);
            oShort.animate().alpha(0f).setStartDelay(375).setDuration(150);
            show.setImageResource(R.drawable.ic_baseline_more_vert);
        }
        listAdapter.notifyItemChanged(position);
    }

监视列表适配器.java

public class WatchListAdapter extends RecyclerView.Adapter<WatchListAdapter.WatchListViewHolder> {
    private ArrayList<WatchListItem> mWatchList;
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }

    public static class WatchListViewHolder extends RecyclerView.ViewHolder {
        public TextView mAssetSymbol;
        public TextView mAssetPrice;
        public ImageView mImageView;
        public ImageView mShowOptions;
        public FloatingActionButton mEditAsset;
        public FloatingActionButton mDeleteAsset;
        public FloatingActionButton mOpenLong;
        public FloatingActionButton mOpenShort;

        public WatchListViewHolder(@NonNull View itemView, final OnItemClickListener listener) {
            super(itemView);
            mAssetSymbol = itemView.findViewById(R.id.assetSymbol);
            mAssetPrice = itemView.findViewById(R.id.assetPrice);
            mImageView = itemView.findViewById(R.id.imageView);
            mShowOptions = itemView.findViewById(R.id.showOptions);
            mEditAsset = itemView.findViewById(R.id.editAsset);
            mDeleteAsset = itemView.findViewById(R.id.deleteAsset);
            mOpenLong = itemView.findViewById(R.id.openLong);
            mOpenShort = itemView.findViewById(R.id.openShort);

            mShowOptions.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (listener != null) {
                        int position = getAdapterPosition();
                        ImageView show = mShowOptions;
                        FloatingActionButton edit = mEditAsset;
                        FloatingActionButton delete = mDeleteAsset;
                        FloatingActionButton oLong = mOpenLong;
                        FloatingActionButton oShort = mOpenShort;
                        if (position != RecyclerView.NO_POSITION) {
                            listener.onShowOptionsClick(position, show, edit, delete, oLong, oShort);
                        }
                    }
                }
            });
        }
    }

    public WatchListAdapter(ArrayList<WatchListItem> watchListArray) {
        mWatchList = watchListArray;
    }

    @NonNull
    @Override
    public WatchListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        return new WatchListViewHolder(v, mListener);
    }

    @Override
    public void onBindViewHolder(@NonNull WatchListViewHolder holder, int position) {
        WatchListItem currentItem = mWatchList.get(position);
        holder.mAssetSymbol.setText(currentItem.getAssetSymbol());
        holder.mAssetPrice.setText(currentItem.getAssetPrice());
        holder.mImageView.setImageResource(currentItem.getImageResource());
    }

    @Override
    public int getItemCount() {
        return mWatchList.size();
    }
}

监视列表项.java

public class WatchListItem {
    private int mImageResource;
    private String mAssetPrice;
    private String mAssetSymbol;

    public WatchListItem(int imageResource, String assetPrice, String assetSymbol) {
        mImageResource = imageResource;
        mAssetPrice = assetPrice;
        mAssetSymbol = assetSymbol;
    }

    public int getImageResource() {
        return mImageResource;
    }

    public String getAssetPrice() {
        return mAssetPrice;
    }

    public String getAssetSymbol() {
        return mAssetSymbol;
    }
}

关于在 MainActivity.java 中放置 listAdapter.setOnItemClickListener 的快速说明:最初它包含在 onCreate() 方法中,因为这是构建 RecyclerView 的地方,也是我试图遵循的教程中放置它的地方; 但我将它移到了engage() 方法,因为这是添加列表项的地方,我认为在该项甚至存在之前设置侦听器是没有意义的,对吗? 无论如何让我知道这是否不正确,正如我怀疑的那样,尽管这并没有改变测试中的行为所以问题是:应用程序打开得很好,将项目添加到 RecyclerView,但是当我单击下拉 ImageView 时,没有。 好吧,并非完全没有,我可以说它正在尝试做某事,但最终什么也没发生。 我能描述它的最好方法是 CardView 类型的“闪烁”和 ImageView 图标被短暂更改为新图标但立即变回,就是这样。 没有错误,没有崩溃; 只是没有执行指定的操作,我不知道为什么。 我不知道为什么他们不得不弃用 ListView,因为如果我不必从头开始构建 onClickListener 接口,这一切对我来说就不那么令人困惑了,但我离题了。 非常感谢您花时间阅读所有这些并提供宝贵的意见。

试试下面的代码,看看它是否有帮助。 我已经更改了两个文件中的一些代码。 您现在不会在每次添加项目时都创建一个新的侦听器,这可能会有所帮助。

主活动.java

public class MainActivity extends AppCompatActivity implements OnClickListener {

    private ArrayList<WatchListItem> watchListArray;
    private RecyclerView watchList;
    private WatchListAdapter listAdapter;
    private RecyclerView.LayoutManager listManager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        watchListArray = new ArrayList<>();
        watchList = (RecyclerView) findViewById(R.id.watchList);
        watchList.setHasFixedSize(true);
        listManager = new LinearLayoutManager(this);
        watchList.setLayoutManager(listManager);
        listAdapter = new WatchListAdapter(watchListArray);
        listAdapter.setOnItemClickListener(new WatchListAdapter.OnItemClickListener() {
            @Override
            public void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
                expandListItem(position, show, edit, delete, oLong, oShort);
            }
        });
        watchList.setAdapter(listAdapter);
    }

    public void engage(Asset asset) {
        int position = watchListArray.size();
        String ticker = asset.getSymbol();
        //Double.toString(asset.getCurrentPrice()) replaced with fixed value for testing
        String price = "390.55";
        //int indicator set to fixed value for testing
        int indicator = R.drawable.ic_bull_indicator;
        watchListArray.add(position, new WatchListItem(indicator, price, ticker));
        listAdapter.notifyItemInserted(position);
    }

    public void expandListItem(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort) {
        if (edit.getVisibility() == View.GONE) {
            show.setImageResource(R.drawable.ic_collapse);
            oShort.animate().alpha(1f).setDuration(150);
            oLong.animate().alpha(1f).setStartDelay(125).setDuration(150);
            delete.animate().alpha(1f).setStartDelay(250).setDuration(150);
            edit.animate().alpha(1f).setStartDelay(375).setDuration(150);
        } else {
            edit.animate().alpha(0f).setDuration(150);
            delete.animate().alpha(0f).setStartDelay(125).setDuration(150);
            oLong.animate().alpha(0f).setStartDelay(250).setDuration(150);
            oShort.animate().alpha(0f).setStartDelay(375).setDuration(150);
            show.setImageResource(R.drawable.ic_baseline_more_vert);
        }
        listAdapter.notifyItemChanged(position);
    }
}

监视列表适配器.java

public class WatchListAdapter extends RecyclerView.Adapter<WatchListAdapter.WatchListViewHolder> {
    private ArrayList<WatchListItem> mWatchList;
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onShowOptionsClick(int position, ImageView show, FloatingActionButton edit, FloatingActionButton delete, FloatingActionButton oLong, FloatingActionButton oShort);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }

    public static class WatchListViewHolder extends RecyclerView.ViewHolder {
        public TextView mAssetSymbol;
        public TextView mAssetPrice;
        public ImageView mImageView;
        public ImageView mShowOptions;
        public FloatingActionButton mEditAsset;
        public FloatingActionButton mDeleteAsset;
        public FloatingActionButton mOpenLong;
        public FloatingActionButton mOpenShort;

        public WatchListViewHolder(@NonNull View itemView, final OnItemClickListener listener) {
            super(itemView);
            mAssetSymbol = itemView.findViewById(R.id.assetSymbol);
            mAssetPrice = itemView.findViewById(R.id.assetPrice);
            mImageView = itemView.findViewById(R.id.imageView);
            mShowOptions = itemView.findViewById(R.id.showOptions);
            mEditAsset = itemView.findViewById(R.id.editAsset);
            mDeleteAsset = itemView.findViewById(R.id.deleteAsset);
            mOpenLong = itemView.findViewById(R.id.openLong);
            mOpenShort = itemView.findViewById(R.id.openShort);
        }
    }

    public WatchListAdapter(ArrayList<WatchListItem> watchListArray) {
        mWatchList = watchListArray;
    }

    @NonNull
    @Override
    public WatchListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        return new WatchListViewHolder(v, mListener);
    }

    @Override
    public void onBindViewHolder(@NonNull WatchListViewHolder holder, int position) {
        WatchListItem currentItem = mWatchList.get(position);
        holder.mAssetSymbol.setText(currentItem.getAssetSymbol());
        holder.mAssetPrice.setText(currentItem.getAssetPrice());
        holder.mImageView.setImageResource(currentItem.getImageResource());
        holder.mShowOptions.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener != null) {
                    ImageView show = holder.mShowOptions;
                    FloatingActionButton edit = holder.mEditAsset;
                    FloatingActionButton delete = holder.mDeleteAsset;
                    FloatingActionButton oLong = holder.mOpenLong;
                    FloatingActionButton oShort = holder.mOpenShort;
                    if (position != RecyclerView.NO_POSITION) {
                        listener.onShowOptionsClick(position, show, edit, delete, oLong, oShort);
                    }
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return mWatchList.size();
    }
}

解决了! 感谢所有花时间回答的人,尤其是 i_A_mok,他的建议最终导致了修复。 我拥有的代码已经足够了; 我只需要在为 alpha 属性设置动画之前将 setVisibilty(View.VISIBLE) 添加到每个 FAB。 出于某种原因,我相信通过从 alpha 0.0 过渡到 alpha 1.0 会自动使视图可见,但可惜事实并非如此:可见性和 alpha 是两个独立的属性,需要独立设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM