Satır / bölüm mantığını iOS'un UITableView'ına benzer şekilde kullanmak, Android'de iOS'ta olduğu kadar basit değildir, ancak RecyclerView'u kullandığınızda - yapabileceklerinizin esnekliği çok daha fazladır.
Sonunda, her şey Adaptörde ne tür bir görünüm görüntülediğinizi nasıl anlayacağınızla ilgili. Bunu bir kez anladığınızda, kolay yelken açmanız gerekir (gerçekten değil, ama en azından bunu halledeceksiniz).
Bağdaştırıcı, geçersiz kılmanız gereken iki yöntemi ortaya çıkarır:
getItemViewType(int position)
Bu yöntemin varsayılan uygulaması her zaman 0 döndürür ve yalnızca 1 tür görünüm olduğunu gösterir. Sizin durumunuzda, öyle değil ve bu nedenle hangi satırın hangi görünüm türüne karşılık geldiğini belirlemenin bir yolunu bulmanız gerekecek. Bunu sizin için satırlar ve bölümlerle yöneten iOS'tan farklı olarak, burada güvenebileceğiniz yalnızca bir dizine sahip olacaksınız ve bir konumun bir bölüm başlığıyla ne zaman ve ne zaman ilişkili olduğunu bilmek için geliştirici becerilerinizi kullanmanız gerekecek. normal bir sıra.
createViewHolder(ViewGroup parent, int viewType)
Yine de bu yöntemi geçersiz kılmanız gerekir, ancak genellikle insanlar viewType parametresini yok sayarlar. Görünüm türüne göre, doğru düzen kaynağını şişirmeniz ve buna göre görünüm tutucunuzu oluşturmanız gerekir. RecyclerView, farklı görünüm türlerinin farklı görünüm türlerinin çakışmasını önleyecek şekilde geri dönüştürülmesini sağlayacaktır.
Varsayılan bir LayoutManager kullanmayı planlıyorsanız, örneğin LinearLayoutManager, gitmekte fayda var . Kendi LayoutManager uygulamanızı yapmayı planlıyorsanız, biraz daha fazla çalışmanız gerekir. Gerçekten çalışmanız gereken tek API, findViewByPosition(int position)belirli bir pozisyonda belirli bir görünümü veren şeydir. Bu görünümün türüne bağlı olarak muhtemelen onu farklı bir şekilde düzenlemek isteyeceğiniz için birkaç seçeneğiniz vardır:
Genellikle ViewHolder modelini kullanırken, görünümün etiketini görünüm tutucu ile ayarlarsınız. Bunu, görünüm yöneticisine bunu ifade eden bir alan ekleyerek görünümün ne tür olduğunu bulmak için yerleşim yöneticisinde çalışma süresi sırasında kullanabilirsiniz.
Hangi konumun hangi görünüm türüyle ilişkili olduğunu belirleyen bir işleve ihtiyacınız olacağından, bu yöntemi bir şekilde küresel olarak erişilebilir hale getirebilirsiniz (belki verileri yöneten bir tekli sınıf olabilir mi?) Ve sonra aynı yöntemi şuna göre sorgulayabilirsiniz: pozisyon.
İşte bir kod örneği:
// in this sample, I use an object array to simulate the data of the list.
// I assume that if the object is a String, it means I should display a header with a basic title.
// If not, I assume it's a custom model object I created which I will use to bind my normal rows.
private Object[] myData;
public static final int ITEM_TYPE_NORMAL = 0;
public static final int ITEM_TYPE_HEADER = 1;
public class MyAdapter extends Adapter<ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ITEM_TYPE_NORMAL) {
View normalView = LayoutInflater.from(getContext()).inflate(R.layout.my_normal_row, null);
return new MyNormalViewHolder(normalView); // view holder for normal items
} else if (viewType == ITEM_TYPE_HEADER) {
View headerRow = LayoutInflater.from(getContext()).inflate(R.layout.my_header_row, null);
return new MyHeaderViewHolder(headerRow); // view holder for header items
}
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final int itemType = getItemViewType(position);
if (itemType == ITEM_TYPE_NORMAL) {
((MyNormalViewHolder)holder).bindData((MyModel)myData[position]);
} else if (itemType == ITEM_TYPE_HEADER) {
((MyHeaderViewHolder)holder).setHeaderText((String)myData[position]);
}
}
@Override
public int getItemViewType(int position) {
if (myData[position] instanceof String) {
return ITEM_TYPE_HEADER;
} else {
return ITEM_TYPE_NORMAL;
}
}
@Override
public int getItemCount() {
return myData.length;
}
}
İşte bu görüntü sahiplerinin nasıl görünmesi gerektiğine dair bir örnek:
public MyHeaderViewHolder extends ViewHolder {
private TextView headerLabel;
public MyHeaderViewHolder(View view) {
super(view);
headerLabel = (TextView)view.findViewById(R.id.headerLabel);
}
public void setHeaderText(String text) {
headerLabel.setText(text);
}
}
public MyNormalViewHolder extends ViewHolder {
private TextView titleLabel;
private TextView descriptionLabel;
public MyNormalViewHolder(View view) {
super(view);
titleLabel = (TextView)view.findViewById(R.id.titleLabel);
descriptionLabel = (TextView)view.findViewById(R.id.descriptionLabel);
}
public void bindData(MyModel model) {
titleLabel.setText(model.getTitle());
descriptionLabel.setText(model.getDescription());
}
}
Elbette bu örnek, veri kaynağınızı (myData) bu şekilde bir bağdaştırıcı uygulamayı kolaylaştıracak şekilde oluşturduğunuzu varsayar. Örnek olarak, bir isim listesi ve adın ilk harfi her değiştiğinde (listenin alfabetik olarak sıralandığını varsayın) için bir başlık gösteren bir veri kaynağını nasıl oluşturacağımı göstereceğim - tıpkı bir kişilere benzer şekilde liste şöyle görünür:
// Assume names & descriptions are non-null and have the same length.
// Assume names are alphabetized
private void processDataSource(String[] names, String[] descriptions) {
String nextFirstLetter = "";
String currentFirstLetter;
List<Object> data = new ArrayList<Object>();
for (int i = 0; i < names.length; i++) {
currentFirstLetter = names[i].substring(0, 1); // get the 1st letter of the name
// if the first letter of this name is different from the last one, add a header row
if (!currentFirstLetter.equals(nextFirstLetter)) {
nextFirstLetter = currentFirstLetter;
data.add(nextFirstLetter);
}
data.add(new MyModel(names[i], descriptions[i]));
}
myData = data.toArray();
}
Bu örnek oldukça spesifik bir sorunu çözmeye geliyor, ancak umarım bu size bir geri dönüşüm cihazında farklı sıra türlerinin nasıl işleneceği konusunda iyi bir genel bakış sağlar ve ihtiyaçlarınıza uyacak şekilde kendi kodunuzda gerekli uyarlamaları yapmanıza olanak tanır.