标签: android-viewholder

ViewHolder模式中setTag和getTag的工作原理是什么?

我有一个简单的代码片段来实现自定义列表视图.

我的代码如下:

WeatherAdapter.java:

public class WeatherAdapter extends ArrayAdapter<weather>{

    Context mcontext; 
    int mlayoutResourceId;    
   weather mdata[] = null;
   View row;

    public WeatherAdapter(Context context, int layoutResourceId, weather[] data) {
        super(context, layoutResourceId, data);
        mlayoutResourceId = layoutResourceId;
       mcontext = context;
        mdata = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      row = convertView;
        WeatherHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ( (Activity) mcontext).getLayoutInflater();
            row = inflater.inflate(mlayoutResourceId, parent, false);

            holder = new WeatherHolder(row);


            row.setTag(holder);

        }
        else
        {
            holder …
Run Code Online (Sandbox Code Playgroud)

android listview android-adapter android-viewholder

12
推荐指数
2
解决办法
2万
查看次数

如何处理RecyclerView.ItemDecoration中的点击事件?

我有一个RecyclerView(带有LinearLayoutManager)和一个自定义的RecyclerView.ItemDecoration.

让我们说,我想在装饰视图中有按钮(出于某种原因......).

我用按钮给布局充气,它画得很好.但我不能使按钮可点击.如果我按下它,没有任何事情发生(它保持不变,没有按下效果)并且onClick事件没有触发.

ItemDecoration布局的结构是

<LinearLayout>
  <TextView/>
  <Button/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

而我正试图在ViewHolder中设置侦听器的装饰

class ItemDecorationHolder extends RecyclerView.ViewHolder {
    public TextView header;
    public Button button;

    public HeaderHolder(View itemView) {
        super(itemView);

        header = (TextView)itemView.findViewById(R.id.header);
        button = (Button)itemView.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //.. Show toast, etc.
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在onDrawOver方法中绘制装饰.(实际上,我正在修改此代码库:https://github.com/edubarr/header-decor)

有任何想法吗?它可行吗?

谢谢!

android android-viewholder android-recyclerview

12
推荐指数
1
解决办法
5068
查看次数

在ViewHolder中绑定

这将是理论问题.

作为每个人,我们在应用程序的许多部分使用RecyclerView.有时,RecyclerView包含不同的项目,不仅包括图像,还包括广告,提示等.这就是为什么我们可以在Adapter中使用getViewType()方法.

但是当我们有很多viewTypes并且在Adapter中绑定它不优雅时会出现问题.所以这就是问题,在ViewHolder中绑定数据是不错的好模式?

假设我们有应用列表.

每个应用程序都有简洁的名称.我们的ViewHolder看起来像这样:

class AppViewHolder extends RecyclerView.ViewHolder {

     public TextView nameText;

     AppViewHolder(View itemView) {
          super(itemView)
          nameText = (TextView) itemView.findViewById(R.id.text_name);
     }
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以添加bind方法:

public void bind(App app) {
     nameText.setText(app.getName());
}
Run Code Online (Sandbox Code Playgroud)

这是好模式吗?

另一种解决方案是使用ViewModel.因为我们在RecyclerView中有不同的项目,所以我们的适配器可以包含类的列表,它是每个ViewModel的基类.

所以基础课是:

class RecyclerViewItem {}
Run Code Online (Sandbox Code Playgroud)

现在是ViewModel for App的类.

class AppRecyclerViewItem extends RecyclerViewItem {

     App app;

     ...
}
Run Code Online (Sandbox Code Playgroud)

和我们的适配器只有RecyclerViewItems列表:

class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    List<RecyclerViewItem> items;

    ...
}
Run Code Online (Sandbox Code Playgroud)

因此,使用这种方法(我的意思是使用ViewModel),最好在ViewHolder或ViewModel中添加bind方法吗?

android android-viewholder android-recyclerview

12
推荐指数
1
解决办法
7653
查看次数

如何从RecyclerView.Adapter中的ViewHolder调用MainActivity方法?

GitHub的一个简单的应用程序项目中,我只有2个自定义Java文件:

  1. MainActivity.java包含与蓝牙和UI相关的源代码
  2. DeviceListAdapter.java包含AdapterViewHolder用于显示蓝牙设备RecyclerView

应用截图

当用户点击蓝牙设备时,MainActivity.java包含一个要调用的方法RecyclerView:

public void confirmConnection(String address) {
    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Do you want to pair to " + device + "?");
    builder.setPositiveButton(R.string.button_ok, 
      new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            device.createBond();
        }
    });
    builder.setNegativeButton(R.string.button_cancel, null);
    builder.show();
}
Run Code Online (Sandbox Code Playgroud)

ViewHolder类(在DeviceListAdapter.java中)中定义了单击侦听器:

public class DeviceListAdapter extends
  RecyclerView.Adapter<DeviceListAdapter.ViewHolder> {

  private ArrayList<BluetoothDevice> mDevices = new ArrayList<BluetoothDevice>();

  protected static …
Run Code Online (Sandbox Code Playgroud)

android android-bluetooth android-viewholder android-recyclerview

11
推荐指数
2
解决办法
1万
查看次数

RecyclerView itemView OnGlobalLayoutListener不会为所有itemViews触发

我有一个RecyclerView在其视图中的构造函数我正在添加一个onGlobalLayoutListener,如下所示

public CustomViewHolder(final View itemView, Context context) {
    super(itemView, context);
    itemView.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
          @Override
          public void onGlobalLayout() {
            // Get height here
          }
     });
}
Run Code Online (Sandbox Code Playgroud)

这会触发itemViews屏幕上可见的所有内容,但是当我滚动recyclerView时,它不会触发itemViews屏幕上显示的那个开始.这是为什么?如何为这些项捕获此侦听器?

android android-viewholder android-recyclerview

11
推荐指数
1
解决办法
2401
查看次数

RecyclerView.ViewHolder总是必须是内部类吗?

我有两个RecyclerView.Adapters使用RecyclerView.ViewHolder与内部类完全相同的s.

我想摆脱代码重复,并使这些ViewHolder免费,独立的类,所以现在全新的类可以被任何RecyclerView.Adapters使用.

但是,我遇到了许多麻烦,例如访问适配器对象的困难.getAdapterPosition()总是回来-1.

所以我改变主意并制作了一个超级RecyclerView.Adapter类,它由这些适配器扩展,并将ViewHolder放在超类中,以便这些适配器可以从子类中使用它.

但我想知道是否ViewHolder必须是一个内在阶级.这让我很生气.请不要建议我结合适配器类,它们是完全不同的,因为ViewHolder它只是一个viewType可以出现在任何特殊的特殊RecyclerView

我在等待你让我感觉更好的更好的方法.

问候.

java android android-viewholder android-recyclerview

11
推荐指数
2
解决办法
2986
查看次数

ViewHolder - 良好的做​​法

一个小小的新手问题.我们为什么要初始化ViewHoldergetView()?为什么我们不能在构造函数中初始化它?

android android-viewholder

10
推荐指数
1
解决办法
1万
查看次数

RecyclerView适配器和ViewHolder动态更新

我正在尝试创建一个将从网络加载新闻的应用程序,并将动态更新.我正在使用RecyclerViewCardView显示内容.我Jsoup用来解析网站.我不认为我的代码是必需的,因为我的问题更具理论性而非实际性.我想了解使用动态更新的过程notifyDataSetChanged().在我的主要活动中,我获取所有标题并将它们添加到列表中.但我需要等待,直到所有项目都加载开始显示它们.我真的很感激,如果有人可以发布我正在尝试做的示例代码,因为我找不到很多关于组合的信息ViewHolder,Adapter并且RecyclerView.

android android-viewholder android-cardview recycler-adapter android-recyclerview

10
推荐指数
1
解决办法
4万
查看次数

如何将两个适配器设置为一个RecyclerView?

我正在开发一个Android应用程序,其中我在'FirebaseDatabase`上存储两种不同类型的信息.

然后在MainActivity,我正在检索它们并向用户显示RecyclerView.这两个信息都是以不同的布局显示的,即两者的布局都不同,这就是为什么我有两个不同的Model类,现在有两个不同的适配器.我正在使用@MikePenz的FastAdapter

所以,我做的是我在recyclerview上设置适配器的顺序与从数据库中获取信息的顺序相同:

1.

public void prepareDataOfSRequests() {
        gModelClass = new GModelClass(postedBy, ***, ***, ***, "error", ***, formattedTime, currentLatitude, currentLongitude, utcFormatDateTime, userEmail, userID, null, ***, itemID);
        fastItemAdapter.add(0, gModelClass);
        recyclerView.setAdapter(fastItemAdapter);
        recyclerView.smoothScrollToPosition(0);
        emptyRVtext.setVisibility(View.INVISIBLE);
    }
Run Code Online (Sandbox Code Playgroud)

2.

public void prepareDataOfERequests() {
        eModelClass = new EModelClass(***, ***, ***, ***, "error", ***, formattedTimeE, currentLatitudeE, currentLongitudeE, utcFormatDateTimeE, userEmailE, userIDE, null, ***, ***, ***, ***, itemID);
        fastItemAdapterER.add(eventRequestsModelClass);
        recyclerView.setAdapter(fastItemAdapterER);
        recyclerView.smoothScrollToPosition(0);
        emptyRVtext.setVisibility(View.INVISIBLE);
    }
Run Code Online (Sandbox Code Playgroud)

由于recyclerview只有一个,我正在逐个设置2个不同的适配器,所以Recyclerview正在使用第二个适配器进行更新并仅显示其内容.

那么,如何将适配器显示或设置为相同的"RecyclerView"并显示存储在两个适配器中的内容.

android android-adapter android-viewholder android-recyclerview fastadapter

10
推荐指数
2
解决办法
1万
查看次数

在RecyclerView.ViewHolder中添加片段

我有一个RecyclerView.ViewHolder,它将根据传递的对象的实例将不同的片段添加到其FrameLayout中。问题来了,几乎不可能在ViewHolder中添加片段。请注意,我已经从父级传递了FragmentManager。最初我尝试使用此代码

public void setSomething(boolean A) {
    if (A) {
         mFragmentManager.beginTransaction()
            .replace(mBinding.typeContainerLayout.getId(), new FragmentA())
            .commit();
    } else {
        mFragmentManager.beginTransaction()
            .replace(mBinding.typeContainerLayout.getId(), new FragmentB())
            .commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码的问题是所有ViewHolder共享相同的ID,因此只有一个ViewHolder可以添加片段。在我的RecyclerView中,只有第一个单元添加了片段。为了解决这个问题,我创建了另一个FrameLayout并将其添加到中typeContainerLayout。现在我的代码变成这样。

public void setSomething(boolean A) {
    FrameLayout frameLayout = new FrameLayout(mContext);
    frameLayout.setId(View.generateViewId());
    mBinding.typeContainerLayout.removeAllViews();
    mBinding.typeContainerLayout.addView(frameLayout)

    if (A) {
         mFragmentManager.beginTransaction()
            .replace(frameLayout.getId(), new FragmentA())
            .commit();
    } else {
        mFragmentManager.beginTransaction()
            .replace(frameLayout.getId(), new FragmentB())
            .commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,每个ViewHolder都正确添加了片段,并拥有自己的片段。但是,当我添加类似5的ViewHolder并尝试向下滚动RecyclerView时,就会出现问题,出现运行时错误

java.lang.IllegalArgumentException: No view found for id 0x4 (unknown) for fragment FragmentA{7c55a69 #0 id=0x4 FragmentA}
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1292)
                      at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
                      at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
                      at …
Run Code Online (Sandbox Code Playgroud)

android android-fragments android-viewholder

10
推荐指数
2
解决办法
1万
查看次数