programing

간단한 Android Recycler보기 보기

batch 2023. 9. 8. 21:19
반응형

간단한 Android Recycler보기 보기

안드로이드 제품을 사용하여 몇 번 항목 목록을 만든 적이 있습니다.RecyclerView, 하지만 그것은 다소 복잡한 과정입니다.수많은 튜토리얼 중 하나를 온라인으로 진행하고 있지만(이것, 이것, 이것이 좋습니다), 빠르게 실행하기 위해 복사하고 붙여넣을 수 있는 베어본 예시를 찾고 있습니다.다음 기능만 필요합니다.

  • 수직배치
  • 각 행에 하나의 텍스트 보기
  • 클릭 이벤트에 응답합니다.

나는 이것을 몇번이나 바랐기 때문에, 나의 향후 참고와 당신의 답변을 위해 아래와 같이 하기로 결정했습니다.

다음은 다음 이미지와 같은 최소한의 예입니다.

RecyclerView with a list of animal names

빈 활동부터 시작합니다.다음 작업을 수행하여 RecyclerView를 추가합니다.각 섹션의 코드를 복사하여 붙여넣기만 하면 됩니다.나중에 필요에 맞게 사용자 지정할 수 있습니다.

  • 그라들에 종속성 추가
  • 활동 및 RecyclerView 행에 대한 xml 레이아웃 파일을 추가합니다.
  • RecyclerView 어댑터 만들기
  • 활동에서 RecyclerView 초기화

그레이들 종속성 업데이트

하십시오. 에 이 합니다 합니다 이 에 .gradle.build선택사항:

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'

버전 번호를 최신 버전으로 업데이트할 수 있습니다.compileimplementationAndroid Studio 2.x의 계속사용하는경우 를

활동 레이아웃 만들기

를 .RecyclerViewxml 레이아웃에 적용할 수 있습니다.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvAnimals"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

행 레이아웃 만들기

각행.RecyclerView단한만질다의다g질as만eyoe의한단TextView파일을 . 새 레이아웃 리소스 파일을 만듭니다.

recyclerview_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>

어댑터 만들기

RecyclerView각 행의 보기를 데이터로 채울 어댑터가 필요합니다.새 Java 파일을 만듭니다.

MyRecyclerViewAdapter.java

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

    private List<String> mData;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor
    MyRecyclerViewAdapter(Context context, List<String> data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    // inflates the row layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
        return new ViewHolder(view);
    }

    // binds the data to the TextView in each row
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String animal = mData.get(position);
        holder.myTextView.setText(animal);
    }

    // total number of rows
    @Override
    public int getItemCount() {
        return mData.size();
    }


    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.tvAnimalName);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    // convenience method for getting data at click position
    String getItem(int id) {
        return mData.get(id);
    }

    // allows clicks events to be caught
    void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

메모들

  • 꼭 필요한 것은 아니지만 행에 클릭 이벤트를 듣기 위한 기능을 포함시켰습니다.구은할수다에e수ne에서 사용할 수 있었습니다.ListViews그리고 공통적으로 필요한 것입니다.이 코드가 필요하지 않으면 제거할 수 있습니다.

활동에서 RecyclerView 초기화

주요 활동에 다음 코드를 추가합니다.

주 활동.java

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

    MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // data to populate the RecyclerView with
        ArrayList<String> animalNames = new ArrayList<>();
        animalNames.add("Horse");
        animalNames.add("Cow");
        animalNames.add("Camel");
        animalNames.add("Sheep");
        animalNames.add("Goat");

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rvAnimals);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new MyRecyclerViewAdapter(this, animalNames);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
    }
}

메모들

  • 은 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ ΔItemClickListener우리가 어댑터에 정의한 것입니다.를해행다수할릭k다sn수ws의 행 클릭 이벤트를 처리할 수 있습니다.onItemClick.

끝났습니다

바로 그겁니다.지금 프로젝트를 실행하고 맨 위에 있는 이미지와 비슷한 것을 얻을 수 있을 것입니다.

진행중

행 사이에 구분자 추가

이렇게 간단한 디바이더를 추가할 수 있습니다.

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
    layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);

좀 더 복잡한 것을 원한다면 다음 답변을 참조하십시오.

클릭 시 행 색상 변경

행을 클릭할 때 배경색을 변경하고 리플 효과를 추가하는 방법은 이 답변을 참조하십시오.

Insert single item

행 업데이트 중

행 추가, 제거 및 업데이트 방법은 이 답변을 참조하십시오.

Insert single item

추가열람

Kotlin 템플릿을 사용할 수 있는 최소 리사이클러 보기:

  • 수직배치
  • 각 행에 하나의 텍스트 보기
  • 클릭 이벤트에 응답합니다(Single and LongPress).

나는 이것이 오래된 실이라는 것을 알고 있으므로 여기에 답하십시오.나중에 참고할 수 있도록 이 답변 추가:

빌드 종속성에서 재사용 보기 추가

  implementation 'com.google.android.material:material:1.4.0-alpha02'
    // RecyclerView
    implementation "androidx.recyclerview:recyclerview:1.2.0"

레이아웃에 재활용 보기 추가

   <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/wifiList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
           /> 

목록 항목(list_item.xml)을 표시할 레이아웃을 만듭니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:padding="5dp"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/ssid"
            android:text="@string/app_name"
            android:layout_width="match_parent"
            android:textSize="17sp"
            android:layout_height="wrap_content" />
        
    </LinearLayout>

</androidx.cardview.widget.CardView>

이제 데이터를 저장할 수 있는 최소한의 어댑터를 만듭니다. 코드는 여기 자체 설명입니다.

 class WifiAdapter(private val wifiList: ArrayList<ScanResult>) : RecyclerView.Adapter<WifiAdapter.ViewHolder>() {

     // holder class to hold reference
    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        //get view reference
        var ssid: TextView = view.findViewById(R.id.ssid) as TextView
    }

     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
         // create view holder to hold reference
         return ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false))
     }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        //set values
        holder.ssid.text =  wifiList[position].SSID
    }

    override fun getItemCount(): Int {
        return wifiList.size
    }
      // update your data
     fun updateData(scanResult: ArrayList<ScanResult>) {
         wifiList.clear()
         notifyDataSetChanged()
         wifiList.addAll(scanResult)
         notifyDataSetChanged()

     }
 }

이 클래스를 추가하여 목록 항목에서 한 번 클릭 및 한 번 길게 클릭 이벤트를 처리합니다.

import android.content.Context;
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    public interface ClickListener {
        void onClick(View view, int position);

        void onLongClick(View view, RecyclerView recyclerView, int position);

    }
    private GestureDetector gestureDetector;
    private ClickListener clickListener;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child,recyclerView,  recyclerView.getChildPosition(child));
                }
            }
        });
    }


    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

마지막으로 목록 항목을 한 번 두 번 두드리면 어댑터를 재활용자 보기로 설정하고 터치 청취자를 추가하여 터치 이벤트 가로채기 시작

    wifiAdapter = WifiAdapter(ArrayList())

    wifiList.apply {
        // vertical layout
        layoutManager = LinearLayoutManager(applicationContext)
        // set adapter
        adapter = wifiAdapter

        // Touch handling
        wifiList.addOnItemTouchListener(RecyclerTouchListener(applicationContext, wifiList, object : RecyclerTouchListener.ClickListener {
            override fun onClick(view: View?, position: Int) {
                Toast.makeText(applicationContext, "RV OnCLickj " + position, Toast.LENGTH_SHORT).show()
            }

            override fun onLongClick(view: View, recyclerView: RecyclerView, position: Int) {
                Toast.makeText(applicationContext, "RV OnLongCLickj " + position, Toast.LENGTH_SHORT).show()
            }
        }
        ))
    }

보너스: 데이터 업데이트

wifiAdapter.updateData(mScanResults as ArrayList<ScanResult>)

결과: enter image description here

리사이클러뷰 구현의 가장 간단한 버전이 될 것입니다.

enter image description here

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view"/>

</FrameLayout>

list_item_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="46dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textview"
        android:text="TextView"
        android:textSize="16dp" />

</LinearLayout>

CustomAdapter.java

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
  private List<String> data;
  public CustomAdapter (List<String> data){
    this.data = data;
  }

  @Override
  public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_view, parent, false);
    return new ViewHolder(rowItem);
  }

  @Override
  public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
    holder.textView.setText(this.data.get(position));
  }

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

  public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    private TextView textView;

    public ViewHolder(View view) {
      super(view);
      view.setOnClickListener(this);
      this.textView = view.findViewById(R.id.textview);
    }

    @Override
    public void onClick(View view) {
      Toast.makeText(view.getContext(), "position : " + getLayoutPosition() + " text : " + this.textView.getText(), Toast.LENGTH_SHORT).show();
    }
  }
}

주 활동.java

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(new CustomAdapter(generateData()));
    recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
  }

  private List<String> generateData() {
    List<String> data = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
      data.add(String.valueOf(i) + "th Element");
    }
    return data;
  }

}

Android RecyclerView

재생 목록 보기 라이브러리를 추가하는 것부터 시작합니다.

implementation 'androidx.recyclerview:recyclerview:1.1.0'

모델 클래스를 만듭니다.

     public class UserModel implements Serializable {

    private String userName;


    public UserModel(String userName) {
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
   }

어댑터 클래스를 만듭니다.

public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.UsersAdapterVh> implements Filterable {

    private List<UserModel> userModelList;
    private List<UserModel> getUserModelListFiltered;
    private Context context;
    private SelectedUser selectedUser;

    public UsersAdapter(List<UserModel> userModelList,SelectedUser selectedUser) {
        this.userModelList = userModelList;
        this.getUserModelListFiltered = userModelList;
        this.selectedUser = selectedUser;
    }

    @NonNull
    @Override
    public UsersAdapter.UsersAdapterVh onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();

        return new UsersAdapterVh(LayoutInflater.from(context).inflate(R.layout.row_users,null));
    }

    @Override
    public void onBindViewHolder(@NonNull UsersAdapter.UsersAdapterVh holder, int position) {

        UserModel userModel = userModelList.get(position);

        String username = userModel.getUserName();
        String prefix = userModel.getUserName().substring(0,1);

        holder.tvUsername.setText(username);
        holder.tvPrefix.setText(prefix);

    }

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

    @Override
    public Filter getFilter() {

        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults filterResults = new FilterResults();

                if(charSequence == null | charSequence.length() == 0){
                    filterResults.count = getUserModelListFiltered.size();
                    filterResults.values = getUserModelListFiltered;

                }else{
                    String searchChr = charSequence.toString().toLowerCase();

                    List<UserModel> resultData = new ArrayList<>();

                    for(UserModel userModel: getUserModelListFiltered){
                        if(userModel.getUserName().toLowerCase().contains(searchChr)){
                            resultData.add(userModel);
                        }
                    }
                    filterResults.count = resultData.size();
                    filterResults.values = resultData;

                }

                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {

                userModelList = (List<UserModel>) filterResults.values;
                notifyDataSetChanged();

            }
        };
        return filter;
    }


    public interface SelectedUser{

        void selectedUser(UserModel userModel);

    }

    public class UsersAdapterVh extends RecyclerView.ViewHolder {

        TextView tvPrefix;
        TextView tvUsername;
        ImageView imIcon;
        public UsersAdapterVh(@NonNull View itemView) {
            super(itemView);
            tvPrefix = itemView.findViewById(R.id.prefix);
            tvUsername = itemView.findViewById(R.id.username);
            imIcon = itemView.findViewById(R.id.imageView);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    selectedUser.selectedUser(userModelList.get(getAdapterPosition()));
                }
            });


        }
    }
}

레이아웃 행 생성_uses.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">

    <RelativeLayout
        android:layout_width="match_parent"
        android:padding="10dp"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:layout_width="50dp"
            android:background="@drawable/users_bg"
            android:layout_height="50dp">
            <TextView
                android:id="@+id/prefix"
                android:layout_width="wrap_content"
                android:textSize="16sp"
                android:textColor="@color/headerColor"
                android:text="T"
                android:layout_centerInParent="true"
                android:layout_height="wrap_content"/>

        </RelativeLayout>
        <TextView
            android:id="@+id/username"
            android:layout_width="wrap_content"
            android:textSize="16sp"
            android:textColor="@color/headerColor"
            android:text="username"
            android:layout_marginStart="90dp"
            android:layout_centerVertical="true"
            android:layout_height="wrap_content"/>
        <ImageView
            android:layout_width="wrap_content"
            android:id="@+id/imageView"
            android:layout_margin="10dp"
            android:layout_alignParentEnd="true"
            android:src="@drawable/ic_navigate_next_black_24dp"
            android:layout_height="wrap_content"/>
    </RelativeLayout>

</LinearLayout>

재생 목록 보기를 찾아 데이터를 채웁니다.

Toolbar toolbar;
RecyclerView recyclerView;

List<UserModel> userModelList = new ArrayList<>();

String[] names = {"Richard","Alice","Hannah","David"};

UsersAdapter usersAdapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = findViewById(R.id.recyclerview);
    toolbar = findViewById(R.id.toolbar);

    this.setSupportActionBar(toolbar);
    this.getSupportActionBar().setTitle("");

    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));

    for(String s:names){
        UserModel userModel = new UserModel(s);

        userModelList.add(userModel);
    }

    usersAdapter = new UsersAdapter(userModelList,this);

    recyclerView.setAdapter(usersAdapter);

}

전체 자습서 및 소스 코드는 여기에서 찾을 수 있습니다.

안드로이드 리사이클러뷰

여기 이를 위한 훨씬 새로운 Kotlin 솔루션이 있습니다. 이 솔루션은 여기에 쓰여 있는 많은 답변보다 훨씬 간단합니다. 익명 클래스를 사용합니다.

val items = mutableListOf<String>()

inner class ItemHolder(view: View): RecyclerView.ViewHolder(view) {
    var textField: TextView = view.findViewById(android.R.id.text1) as TextView
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    rvitems.layoutManager = LinearLayoutManager(context)
    rvitems.adapter = object : RecyclerView.Adapter<ItemHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {
            return ItemHolder(LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false))
        }

        override fun getItemCount(): Int {
            return items.size
        }

        override fun onBindViewHolder(holder: ItemHolder, position: Int) {
            holder.textField.text = items[position]
            holder.textField.setOnClickListener {
                Toast.makeText(context, "Clicked $position", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

저는 자유롭게 안드로이드를 사용했습니다.R.layout.simple_list_item_1은 간단할수록 늘어납니다.좀 더 단순화해서 아이템을 넣고 싶었습니다.내부 클래스로 보유하고 있지만 외부 클래스 매개 변수의 유형에서 참조하는 방법을 제대로 파악할 수 없습니다.

시작하려면 Recycler 보기에서 보기만 하면 됩니다.

리사이클러 뷰 어댑터는 이런 것일 수 있습니다.

class CustomAdapter: RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
    var data =  listOf<String>()
        set(value) {
            field = value
            notifyDataSetChanged()
        }
    override fun getItemCount() =data.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.txt.text= data[position]
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
        )
    }


    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        val txt: TextView = itemView.findViewById(R.id.item_text_view)
    }
}

어댑터를 리사이클러 뷰에 부착하고 어댑터에 데이터를 부착합니다.

val view = findViewById<RecyclerView>(R.id.recycler_view)                                              
val adapter = CustomAdapter()                                                                          
val data = listOf("text1", "text2", "text3")
adapter.data = data                                                                             
view.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
view.adapter = adapter       
            

여러 출처를 바탕으로 단순 라이브러리를 사용하여 재활용자 보기의 단순 구현을 만들었습니다.

이 줄을 에 추가합니다.build.gradle

implementation 'com.hereshem.lib:awesomelib:2.0.1'

Add Activity_main.xml에 MyRecyclerView를 추가하여 RecyclerView를 생성합니다.

<com.hereshem.lib.recycler.MyRecyclerView
        android:id="@+id/recycler"
        app:layoutManager="LinearLayoutManager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

이제 기본 활동에서 보기 만들기바인딩이 필요한 클래스의 이름을 전달하여 보유자

public static class EVHolder extends MyViewHolder<Events> {
    TextView date, title, summary;
    public EVHolder(View v) {
        super(v);
        date = v.findViewById(R.id.date);
        title = v.findViewById(R.id.title);
        summary = v.findViewById(R.id.summary);
    }
    @Override
    public void bindView(Events c) {
        date.setText(c.date);
        title.setText(c.title);
        summary.setText(c.summary);
    }
}

어댑터의 항목, 클래스 및 레이아웃을 전달하여 줄 수가 매우 적은 변수 및 어댑터 목록 만들기

List<Events> items = new ArrayList<>();
MyRecyclerView recycler = findViewById(R.id.recycler);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, items, EVHolder.class, R.layout.row_event);
recycler.setAdapter(adapter);

ClickListener는 다음 행으로 추가할 수 있습니다.

recycler.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {
    @Override
    public void onItemClick(int position) {
        Toast.makeText(MainActivity.this, "Recycler Item Clicked " + position, Toast.LENGTH_SHORT).show();
    }
});

다 됐습니다.

더 많은 예와 구현 방법은 여기에서 확인할 수 있습니다.도움이 되길 바랍니다!!!

이제 모두를 위해 어댑터 하나가 필요합니다.RecyclerView

  • 에서 하나의 어댑터를 모든 RecyclerView에 사용할 수 있습니다.그래서 NO onBindViewHolder, 아니요 onCreateViewHolder처리.
  • Java/Kotlin 클래스에서 어댑터를 설정할 코드가 없습니다.샘플 클래스를 확인합니다.
  • 바인딩 어댑터를 사용하여 모든 목록에 대한 이벤트 및 사용자 지정 데이터를 설정할 수 있습니다.

screenshot

다른 을 을 에 RecyclerView 기준 -터 1준 -

activity_home.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="listOne"
            type="java.util.List"/>

        <variable
            name="listTwo"
            type="java.util.List"/>

        <variable
            name="onItemClickListenerOne"
            type="com.ks.nestedrecyclerbindingexample.callbacks.OnItemClickListener"/>

        <variable
            name="onItemClickListenerTwo"
            type="com.ks.nestedrecyclerbindingexample.callbacks.OnItemClickListener"/>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            rvItemLayout="@{@layout/row_one}"
            rvList="@{listOne}"
            rvOnItemClick="@{onItemClickListenerOne}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager"
            />

        <android.support.v7.widget.RecyclerView
            rvItemLayout="@{@layout/row_two}"
            rvList="@{listTwo}"
            rvOnItemClick="@{onItemClickListenerTwo}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager"
            />

    </LinearLayout>

</layout>

I pass list, item layout id, click listen from layout.

rvItemLayout="@{@layout/row_one}"
rvList="@{listOne}"
rvOnItemClick="@{onItemClickListenerOne}"

이 사용자 지정 특성은 BindingAdapter에 의해 생성됩니다.

public class BindingAdapters {
    @BindingAdapter(value = {"rvItemLayout", "rvList", "rvOnItemClick"}, requireAll = false)
    public static void setRvAdapter(RecyclerView recyclerView, int rvItemLayout, List rvList, @Nullable OnItemClickListener onItemClickListener) {
        if (rvItemLayout != 0 && rvList != null && rvList.size() > 0)
            recyclerView.setAdapter(new GeneralAdapter(rvItemLayout, rvList, onItemClickListener));
    }
}

이제 활동에서 목록을 통과하고 청취자 좋아요를 클릭합니다.

홈 액티비티.java

public class HomeActivity extends AppCompatActivity {
    ActivityHomeBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
        binding.setListOne(new ArrayList()); // pass your list or set list from response of API
        binding.setListTwo(new ArrayList());
        binding.setOnItemClickListenerOne(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, Object object) {
                if (object instanceof ModelParent) {
                    // TODO: your action here
                }
            }
        });
        binding.setOnItemClickListenerTwo(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, Object object) {
                if (object instanceof ModelChild) {
                    // TODO: your action here  
                }
            }
        });
    }
}

너무 많이 읽고 싶지는 않을 것입니다. 내 github repo에서 전체 예제를 직접 복제/다운로드하십시오.그리고 직접 해보세요.

를 볼 수 .GeneralAdapter.java최상의 조건으로

데이터 바인딩을 설정하는 동안 문제가 발생하면 이 답변을 참조하십시오.

종속성

compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.lguipeng.bubbleview:library:1.0.0'
compile 'com.larswerkman:HoloColorPicker:1.5'
compile 'com.mcxiaoke.volley:library-aar:1.0.0'

클릭 항목에 대한 하나의 클래스

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildPosition(childView));
            return true;
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }


}

2등급 리사이클러 보기

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;

public class SLByTopics extends Fragment {


    public static ArrayList<MByTopics> byTopicsMainArrayList=new ArrayList<>();


    TabRefreshReceiver tabRefreshReceiver;
    RecyclerView recyclerView;
    SAdpByTopics sAdpByTopics;
    public ArrayList<MByTopics> mByTopicsArrayList=new ArrayList<>();
    ProgressDialog progressDialog;

    public SLByTopics(){
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.sl_fragment_by_topics, container, false);

        progressDialog = new ProgressDialog(getActivity());
        if (IsOnline.isNetworkAvailable(getActivity())) {
            getCategoryTree();
        } else{
            IsOnline.showNoInterNetMessage(getActivity());
        }
        tabRefreshReceiver = new TabRefreshReceiver();
       LocalBroadcastManager.getInstance(getContext()).registerReceiver(tabRefreshReceiver, new IntentFilter("BY_TOPICS"));

        setUpView(view);
        return view;
    }

    private void setUpView(View view) {

        recyclerView=(RecyclerView)view.findViewById(R.id.by_topics_list_recyclerView);
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
    }

    @Override
    public void onResume() {
        super.onResume();

        recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, final int position) {

                if (mByTopicsArrayList.get(position).getChild().size()>0){
                    Intent intent = new Intent(getActivity(), SByTopicCategory.class);
                    intent.putExtra("selectedCategoryName",mByTopicsArrayList.get(position).getCatname());
                    intent.putExtra("jsonData",mByTopicsArrayList.get(position).getMainTopicJson());
                    startActivity(intent);
                    getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
                }else {
                    Intent intent = new Intent(getActivity(), SByCategoryQuestionList.class);
                    intent.putExtra("selectedSubCategoryName",mByTopicsArrayList.get(position).getCatname());
                    intent.putExtra("catID",mByTopicsArrayList.get(position).getId());
                    startActivity(intent);
                    getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
                }
            }
        }));

    }

    private class TabRefreshReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.detach(SLByTopics.this).attach(SLByTopics.this).commit();
                LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(tabRefreshReceiver);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    private void getCategoryTree() {
        progressDialog.setMessage("Please Wait...");
        progressDialog.setCancelable(false);
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, Const.HOSTNAME + Const.STUDENT_GET_CATEGORY_TREE,
                new Response.Listener<String>() {
                    @SuppressLint("LongLogTag")
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject object = new JSONObject(response);
                            String status = object.getString("status");
                            int i = Integer.parseInt(status);

                            switch (i) {

                                case 0:
                                    progressDialog.dismiss();
//                                    Toast.makeText(getActivity(), "getCategorySuccess", Toast.LENGTH_SHORT).show();
                                    Log.e("getCategoryTree Response", "getCategoryTree Response : " + response);

                                    try {    
                                        byTopicsMainArrayList.clear();
                                        JSONArray info = object.getJSONArray("info");
                                        if (info.length() > 0) {
                                            for (i = 0; i < info.length(); i++) {
                                                JSONObject data = info.getJSONObject(i);
                                                MByTopics mByTopics = new MByTopics();
                                                mByTopics.setId(data.getString("id"));
                                                mByTopics.setCatname(data.getString("catname"));
                                                mByTopics.setMainTopicJson(data.toString());

                                                JSONArray topicChildren = data.getJSONArray("children");
                                                ArrayList<SMByTopicCategory> byChildrenArrayList = new ArrayList<>();

                                                for (int j = 0; j < topicChildren.length(); j++) {
                                                    JSONObject topicChildrenData = topicChildren.getJSONObject(j);
                                                    SMByTopicCategory smByTopicCategory = new SMByTopicCategory();
                                                    smByTopicCategory.setId(topicChildrenData.getString("id"));
                                                    smByTopicCategory.setCatname(topicChildrenData.getString("catname"));
                                                    smByTopicCategory.setChildTopicJson(topicChildrenData.toString());

                                                    JSONArray topicChildrenQuestion = topicChildrenData.getJSONArray("children");
                                                    ArrayList<SMByTopicSubCategory> byChildrenSubArrayList = new ArrayList<>();

                                                    for (int k = 0; k < topicChildrenQuestion.length(); k++) {
                                                        JSONObject topicChildrenSubData = topicChildrenQuestion.getJSONObject(k);
                                                        SMByTopicSubCategory smByTopicSubCategory = new SMByTopicSubCategory();
                                                        smByTopicSubCategory.setId(topicChildrenSubData.getString("id"));
                                                        smByTopicSubCategory.setCatname(topicChildrenSubData.getString("catname"));
                                                        smByTopicSubCategory.setChildSubTopicJson(topicChildrenSubData.toString());

                                                        byChildrenSubArrayList.add(smByTopicSubCategory);
                                                    }

                                                    smByTopicCategory.setQuestions(byChildrenSubArrayList);

                                                    byChildrenArrayList.add(smByTopicCategory);
                                                }
                                                mByTopics.setChild(byChildrenArrayList);
                                                byTopicsMainArrayList.add(mByTopics);
                                            }


                                            mByTopicsArrayList.clear();
                                            mByTopicsArrayList=byTopicsMainArrayList;
                                            sAdpByTopics=new SAdpByTopics(mByTopicsArrayList,getActivity());
                                            recyclerView.setAdapter(sAdpByTopics);
                                            sAdpByTopics.notifyDataSetChanged();

                                        }

                                    }catch (Exception e){
                                        e.printStackTrace();
                                    }
                                    break;

                                default:
                                    progressDialog.dismiss();
//                                    Toast.makeText(getActivity(), "getCategoryError : " + response, Toast.LENGTH_SHORT).show();
                                    Log.e("getCategoryTree Not Response", "getCategoryTree Uploading Not Response : " + response);
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        progressDialog.dismiss();
                        Log.e("getCategoryTree Error :","getCategoryTree Error :"+error.getMessage());
//                        Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
                    }
                }){

        };/* {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {

                Map<String, String> map = new HashMap<String, String>();
//                map.put("uid", String.valueOf(ConfigManager.getUserId()));
                return map;
            }
        };*/

        stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                0,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.add(stringRequest);
    }
}

재활용품 품목의 어댑터 클래스

import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;

public class SAdpByTopics extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        ArrayList<MByTopics> topicsArrayList=new ArrayList<>();
        Activity activity;

     public SAdpByTopics(ArrayList<MByTopics> topicsArrayList,Activity activity){
        this.topicsArrayList=topicsArrayList;
        this.activity=activity;
     }

     @Override
     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemeView= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_by_topic_list,parent,false);
        RecyclerView.ViewHolder holder=new Holder(itemeView);
        holder.setIsRecyclable(false);
        return holder;
     }

     @Override
     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
         final Holder classHolder = (Holder) holder;
         try{
             classHolder.txt_topic_name.setText(topicsArrayList.get(position).getCatname());
         }catch (Exception e){
             e.printStackTrace();
         }
     }

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


class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView txt_topic_name;

    public Holder(View itemView) {
        super(itemView);
        txt_topic_name = (TextView) itemView.findViewById(R.id.txt_topic_name);
    }

    @Override
    public void onClick(View v) {

    }
}
}

모듈 클래스

public class MByTopics {

    String id;
    String topicName;
    String catname;
    String MainTopicJson;
    ArrayList<SMByTopicCategory> child;
    ArrayList<SMByTopicSubCategory> questions;

    public void setId(String id){
        this.id=id;
    }
    public String getId(){
        return  id;
    }

    public void setCatname(String catname) {
        this.catname = catname;
    }

    public String getCatname() {
        return catname;
    }

    public void setTopicName(String topicName) {
        this.topicName = topicName;
    }
    public String getTopicName() {
        return topicName;
    }

    public void setChild(ArrayList<SMByTopicCategory> child) {
        this.child = child;
    }

    public String getMainTopicJson() {
        return MainTopicJson;
    }

    public void setMainTopicJson(String mainTopicJson) {
        MainTopicJson = mainTopicJson;
    }

    public ArrayList<SMByTopicCategory> getChild() {
        return child;
    }

    public void setQuestions(ArrayList<SMByTopicSubCategory> questions) {
        this.questions = questions;
    }

    public ArrayList<SMByTopicSubCategory> getQuestions() {
        return questions;
    }

    public ArrayList<MByTopics> getByTopicList() {
        ArrayList<MByTopics> mByTopicsArrayList = new ArrayList<>();

        for (int i=0;i<11;i++){
            MByTopics mQuestionBankCategory=new MByTopics();

            if (i==1 || i== 5|| i==9){
                mQuestionBankCategory.setTopicName("Microeconomics");
            }else  if (i==2 || i== 10|| i==6) {
                mQuestionBankCategory.setTopicName("Macroeconomics");
            }else {
                mQuestionBankCategory.setTopicName("Current Isssues");
            }

            mByTopicsArrayList.add(mQuestionBankCategory);
        }

        return mByTopicsArrayList;
    }

}

아직 댓글을 달 수 없기 때문에 답으로 링크를 올리겠습니다.리사이클러뷰 http://www.androiddeft.com/2017/10/01/recyclerview-android/ 에서 간단하고 잘 정리된 튜토리얼을 찾았습니다.

활동에 리사이클러 보기를 추가할 때 외에 수행하고자 하는 작업은 아래와 같으며 이 작업을 수행하는 방법은 링크에 설명되어 있습니다.

  • 레이아웃 파일에 RecyclerView 구성 요소 추가
  • 목록 행으로 표시할 클래스 만들기
  • 목록 행의 레이아웃인 레이아웃 파일을 만듭니다.
  • 이제 사용자 지정 어댑터가 필요하므로 상위 클래스인 RecyclerView에서 확장하여 사용자 지정 어댑터를 생성합니다.어댑터
  • 작성 시 기본 활동에 재생성 보기 추가
  • 구분 기호 추가
  • 터치 청취자 추가

디퓨틸과 필터가 있는 추상 어댑터를 사용할 수 있습니다.

단순추상 어댑터.kt

abstract class SimpleAbstractAdapter<T>(private var items: ArrayList<T> = arrayListOf()) : RecyclerView.Adapter<SimpleAbstractAdapter.VH>() {
   protected var listener: OnViewHolderListener<T>? = null
   private val filter = ArrayFilter()
   private val lock = Any()
   protected abstract fun getLayout(): Int
   protected abstract fun bindView(item: T, viewHolder: VH)
   protected abstract fun getDiffCallback(): DiffCallback<T>?
   private var onFilterObjectCallback: OnFilterObjectCallback? = null
   private var constraint: CharSequence? = ""

override fun onBindViewHolder(vh: VH, position: Int) {
    getItem(position)?.let { bindView(it, vh) }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
    return VH(parent, getLayout())
}

override fun getItemCount(): Int = items.size

protected abstract class DiffCallback<T> : DiffUtil.Callback() {
    private val mOldItems = ArrayList<T>()
    private val mNewItems = ArrayList<T>()

    fun setItems(oldItems: List<T>, newItems: List<T>) {
        mOldItems.clear()
        mOldItems.addAll(oldItems)
        mNewItems.clear()
        mNewItems.addAll(newItems)
    }

    override fun getOldListSize(): Int {
        return mOldItems.size
    }

    override fun getNewListSize(): Int {
        return mNewItems.size
    }

    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return areItemsTheSame(
                mOldItems[oldItemPosition],
                mNewItems[newItemPosition]
        )
    }

    abstract fun areItemsTheSame(oldItem: T, newItem: T): Boolean

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return areContentsTheSame(
                mOldItems[oldItemPosition],
                mNewItems[newItemPosition]
        )
    }

    abstract fun areContentsTheSame(oldItem: T, newItem: T): Boolean
}

class VH(parent: ViewGroup, @LayoutRes layout: Int) : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false))

interface OnViewHolderListener<T> {
    fun onItemClick(position: Int, item: T)
}

fun getItem(position: Int): T? {
    return items.getOrNull(position)
}

fun getItems(): ArrayList<T> {
    return items
}

fun setViewHolderListener(listener: OnViewHolderListener<T>) {
    this.listener = listener
}

fun addAll(list: List<T>) {
    val diffCallback = getDiffCallback()
    when {
        diffCallback != null && !items.isEmpty() -> {
            diffCallback.setItems(items, list)
            val diffResult = DiffUtil.calculateDiff(diffCallback)
            items.clear()
            items.addAll(list)
            diffResult.dispatchUpdatesTo(this)
        }
        diffCallback == null && !items.isEmpty() -> {
            items.clear()
            items.addAll(list)
            notifyDataSetChanged()
        }
        else -> {
            items.addAll(list)
            notifyDataSetChanged()
        }
    }
}

fun add(item: T) {
    items.add(item)
    notifyDataSetChanged()
}

fun add(position:Int, item: T) {
    items.add(position,item)
    notifyItemInserted(position)
}

fun remove(position: Int) {
    items.removeAt(position)
    notifyItemRemoved(position)
}

fun remove(item: T) {
    items.remove(item)
    notifyDataSetChanged()
}

fun clear(notify: Boolean=false) {
    items.clear()
    if (notify) {
        notifyDataSetChanged()
    }
}

fun setFilter(filter: SimpleAdapterFilter<T>): ArrayFilter {
    return this.filter.setFilter(filter)
}

interface SimpleAdapterFilter<T> {
    fun onFilterItem(contains: CharSequence, item: T): Boolean
}

fun convertResultToString(resultValue: Any): CharSequence {
    return filter.convertResultToString(resultValue)
}

fun filter(constraint: CharSequence) {
    this.constraint = constraint
    filter.filter(constraint)
}

fun filter(constraint: CharSequence, listener: Filter.FilterListener) {
    this.constraint = constraint
    filter.filter(constraint, listener)
}

fun getFilter(): Filter {
    return filter
}

interface OnFilterObjectCallback {
    fun handle(countFilterObject: Int)
}

fun setOnFilterObjectCallback(objectCallback: OnFilterObjectCallback) {
    onFilterObjectCallback = objectCallback
}

inner class ArrayFilter : Filter() {
    private var original: ArrayList<T> = arrayListOf()
    private var filter: SimpleAdapterFilter<T> = DefaultFilter()
    private var list: ArrayList<T> = arrayListOf()
    private var values: ArrayList<T> = arrayListOf()


    fun setFilter(filter: SimpleAdapterFilter<T>): ArrayFilter {
        original = items
        this.filter = filter
        return this
    }

    override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
        val results = Filter.FilterResults()
        if (constraint == null || constraint.isBlank()) {
            synchronized(lock) {
                list = original
            }
            results.values = list
            results.count = list.size
        } else {
            synchronized(lock) {
                values = original
            }
            val result = ArrayList<T>()
            for (value in values) {
                if (constraint!=null && constraint.trim().isNotEmpty() && value != null) {
                    if (filter.onFilterItem(constraint, value)) {
                        result.add(value)
                    }
                } else {
                    value?.let { result.add(it) }
                }
            }
            results.values = result
            results.count = result.size
        }
        return results
    }

    override fun publishResults(constraint: CharSequence, results: Filter.FilterResults) {
        items = results.values as? ArrayList<T> ?: arrayListOf()
        notifyDataSetChanged()
        onFilterObjectCallback?.handle(results.count)
    }

}

class DefaultFilter<T> : SimpleAdapterFilter<T> {
    override fun onFilterItem(contains: CharSequence, item: T): Boolean {
        val valueText = item.toString().toLowerCase()
        if (valueText.startsWith(contains.toString())) {
            return true
        } else {
            val words = valueText.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
            for (word in words) {
                if (word.contains(contains)) {
                    return true
                }
            }
        }
        return false
    }
  }
}

그리고 구현 방법으로 추상 어댑터를 확장합니다.

태스크Adapter.kt

import android.annotation.SuppressLint
  import kotlinx.android.synthetic.main.task_item_layout.view.*

class TasksAdapter(private val listener:TasksListener? = null) : SimpleAbstractAdapter<Task>() {
override fun getLayout(): Int {
    return R.layout.task_item_layout
}

override fun getDiffCallback(): DiffCallback<Task>? {
    return object : DiffCallback<Task>() {
        override fun areItemsTheSame(oldItem: Task, newItem: Task): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Task, newItem: Task): Boolean {
            return oldItem.items == newItem.items
        }
    }
}

@SuppressLint("SetTextI18n")
override fun bindView(item: Task, viewHolder: VH) {
    viewHolder.itemView.apply {
        val position = viewHolder.adapterPosition
        val customer = item.customer
        val customerName = if (customer != null) customer.name else ""
        tvTaskCommentTitle.text = customerName + ", #" + item.id
        tvCommentContent.text = item.taskAddress
        ivCall.setOnClickListener {
            listener?.onCallClick(position, item)
        }
        setOnClickListener {
            listener?.onItemClick(position, item)
        }
    }
}

 interface TasksListener : SimpleAbstractAdapter.OnViewHolderListener<Task> {
    fun onCallClick(position: Int, item: Task)
 }
}

Init 어댑터

mAdapter = TasksAdapter(object : TasksAdapter.TasksListener {
            override fun onCallClick(position: Int, item:Task) {
            }

            override fun onItemClick(position: Int, item:Task) {

            }
        })
rvTasks.adapter = mAdapter

채움

mAdapter?.addAll(tasks)

사용자 지정 필터 추가

mAdapter?.setFilter(object : SimpleAbstractAdapter.SimpleAdapterFilter<MoveTask> {
            override fun onFilterItem(contains: CharSequence, item:Task): Boolean {
                return contains.toString().toLowerCase().contains(item.id?.toLowerCase().toString())
            }
    })

데이터를 필터링하다

mAdapter?.filter("test")

구현 Androidx.proview:proview:......다음에 나와 있는 Androidx 라이브러리로 업데이트하는 것이 좋습니다.

https://developer.android.com/jetpack/androidx/releases/recyclerview

레이아웃 파일 Widget XML 태그를 Androidx.recyclerview로 업데이트해야 합니다.위젯.리사이클러뷰

이러한 "최소" 예의 대부분이 단순한 도구를 만들기 위해 최소 4개의 다른 파일을 만드는 것을 포함한다는 것은 저만 제정신이 아니라는 것을 알게 된 것이 아닙니다.

다음은 Kotlin(Saifur Rahman Mohsin의 이 답변을 토대로 구축된)의 독립형 활동으로 기본적인 재활용 보기를 구현합니다.

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class ModelDownloaderActivity : AppCompatActivity() {

    val items = (1..50).toList().map { "Item #$it" }
    inner class ItemHolder(view: View, var textField: TextView = view.findViewById(android.R.id.text1)) : RecyclerView.ViewHolder(view)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Create recycler view, or find it in Activity's XML file if you prefer
        val myLayoutResource: Int? = null // Replace with R.layout.activity_model_downloader if you want to use an XML layout with a recycler view in it
        val recyclerView = myLayoutResource?.let {
            setContentView(it)
            findViewById(R.id.modelRecyclerView) // Replace with ID of your recycler view in layout
        } ?: RecyclerView(this).also { setContentView(ConstraintLayout(this).apply { addView(it) }) }

        // Bind controls to it.
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = object : RecyclerView.Adapter<ItemHolder>() {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
                ItemHolder(LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false))
            override fun getItemCount() = items.size
            override fun onBindViewHolder(holder: ItemHolder, position: Int) {
                holder.textField.text = items[position]
                holder.textField.setOnClickListener {
                    Toast.makeText(this@ModelDownloaderActivity, "Clicked $position", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}

언급URL : https://stackoverflow.com/questions/40584424/simple-android-recyclerview-example

반응형