У меня есть дочерний макет и родительский макет, как показано ниже. Мне нужно выбрать несколько элементов в дочернем макете. Я могу выбрать несколько элементов, но столкнулся с двумя проблемами. 1. При прокрутке выбранный элемент меняется. 2. Когда я выбираю элемент в первой строке, также выбирается строка элемента 4.
Вот мой код.
Родительский макет:
<?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">
<RelativeLayout
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_alignParentTop = "true"
android:id = "@+id/formsheader">
<include
android:id = "@+id/formToolbar"
layout = "@layout/toolbar" />
</RelativeLayout>
<RelativeLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:orientation = "vertical"
android:background = "#e9e7e9"
android:layout_above = "@+id/formsfooter"
android:layout_below = "@+id/formsheader"
android:id = "@+id/teamFormsContent">
<GridView
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:columnWidth = "137dp"
android:numColumns = "auto_fit"
android:verticalSpacing = "20dp"
android:horizontalSpacing = "20dp"
android:stretchMode = "columnWidth"
android:layout_marginLeft = "23dp"
android:layout_marginRight = "23dp"
android:layout_centerHorizontal = "true"
android:layout_centerVertical = "true"
android:scrollbars = "none"
android:id = "@+id/form_gridView" />
</RelativeLayout>
<RelativeLayout
android:layout_width = "match_parent"
android:layout_height = "50dp"
android:layout_alignParentBottom = "true"
android:id = "@+id/formsfooter"
android:layout_gravity = "center"
android:gravity = "center"
android:layout_centerHorizontal = "true"
android:layout_centerVertical = "true"
android:background = "#051b2e">
<TextView
android:id = "@+id/idletext"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Idle"
android:textColor = "#47b8fd"
android:textSize = "15dp"
android:textAppearance = "?android:attr/textAppearanceMedium" />
<TextView
android:id = "@+id/tapToViewText"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Tap to view"
android:textColor = "#ffffff"
android:textSize = "15dp"
android:layout_marginLeft = "20dp"
android:layout_toRightOf = "@+id/idletext"
android:textAppearance = "?android:attr/textAppearanceMedium" />
</RelativeLayout>
</RelativeLayout>
child_layout:
<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:orientation = "vertical">
<LinearLayout
android:id = "@+id/form_layout"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_marginTop = "30dp"
android:layout_gravity = "center"
android:background = "@android:color/white"
android:orientation = "vertical">
<LinearLayout
android:id = "@+id/form_view_layout"
android:layout_width = "137dp"
android:layout_height = "178dp"
android:orientation = "vertical"
android:layout_marginTop = "3dp"
android:layout_marginBottom = "3dp"
android:layout_marginLeft = "3dp"
android:layout_marginRight = "3dp"
android:layout_gravity = "center"
android:weightSum = "100"
android:background = "@android:color/white">
<ImageView
android:src = "@drawable/image1"
android:layout_width = "match_parent"
android:layout_height = "0dp"
android:layout_weight = "72"
android:layout_gravity = "center"
android:id = "@+id/form_Image" />
<TextView
android:text = "sometext"
android:textAppearance = "?android:attr/textAppearanceSmall"
android:layout_width = "match_parent"
android:layout_height = "0dp"
android:textColor = "#00ccff"
android:textSize = "12dp"
android:layout_marginLeft = "10dp"
android:layout_marginBottom = "5dp"
android:layout_weight = "18"
android:id = "@+id/heading" />
<TextView
android:text = "sometext"
android:textAppearance = "?android:attr/textAppearanceSmall"
android:layout_width = "match_parent"
android:layout_height = "0dp"
android:textSize = "12dp"
android:layout_weight = "10"
android:layout_marginBottom = "10dp"
android:textColor = "@android:color/black"
android:layout_marginLeft = "10dp"
android:id = "@+id/subHeading1" />
</LinearLayout>
</LinearLayout>
<TextView
android:text = "sometext"
android:textAppearance = "?android:attr/textAppearanceSmall"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:textColor = "@android:color/black"
android:textSize = "13dp"
android:layout_below = "@+id/form_view_layout"
android:layout_marginTop = "10dp"
android:layout_gravity = "center"
android:gravity = "center"
android:id = "@+id/subHeading2" />
<TextView
android:text = "14/01/1997 5:00"
android:textAppearance = "?android:attr/textAppearanceSmall"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:textColor = "#696969"
android:textSize = "13dp"
android:layout_below = "@+id/subHeading2"
android:layout_marginTop = "7dp"
android:layout_gravity = "center"
android:gravity = "center"
android:id = "@+id/formupdateddatetime" />
</LinearLayout>
Код активности и адаптера:
namespace FormSample.Activities
{
[Activity(Label = "FormsActivity")]
public class FormsActivity : BaseActivity
{
protected override int Layout => Resource.Layout.Forms;
private FormModel _formModel;
List<Form> formsList = new List<Form>();
List<Form> formsListToDelete = new List<Form>();
private bool _isMultiSelect;
public override void OnBackPressed()
{
FinishAffinity();
}
public static Intent NewIntent(Context context)
{
try
{
var intent = new Intent(context, typeof(FormsActivity));
return intent;
}
catch (Exception exception)
{
return null;
}
}
protected async override void FindViewElements()
{
try
{
_formModel = new FormModel()
{
Form = FindViewById<GridView>(Resource.Id.form_gridView),
FormToolbar = FindViewById<Toolbar>(Resource.Id.formToolbar)
};
formsList = new List<Form>();
var teamForms = new List<Form>();
List<TeamlistResponse> _fromsListFromLocal = await LocalService.Instance.GetFormsCreatedInLocal();
foreach (var form in _fromsListFromLocal)
{
var localForm = ConvertTeamsListDtoToForm(form);
formsList.Add(localForm);
}
formsList = formsList.OrderByDescending(x => x.modified_timestamp).ToList();
InitializeScreen();
LoggingManager.Exit("MethodName:FindViewElements And ActivityName:FormsActivity");
}
catch (Exception exception)
{
LoggingManager.Error(exception, "FindViewElements", "FormsActivity");
}
}
public void InitializeScreen()
{
try
{
LoggingManager.Enter("MethodName:InitializeScreen And ActivityName:FormsActivity");
SetSupportActionBar(_formModel.FormToolbar);
GetListOfForms();
LoggingManager.Exit("MethodName:InitializeScreen And ActivityName:FormsActivity");
}
catch (Exception exception)
{
LoggingManager.Error(exception, "InitializeScreen", "FormsActivity");
}
}
private void GetListOfForms()
{
_formModel.Form.ItemClick += Form_Click;
_formModel.Form.Adapter = new FormAdapter(formsList, this);
}
private async void Form_Click(Object sender, AdapterView.ItemClickEventArgs e)
{
try
{
var selectedItem = formsList[e.Position];
if (selectedItem.Caption != "New Form" && selectedItem.id != null)
{
View selectedForm = e.View;
LinearLayout selectedFormLayout = selectedForm.FindViewById<LinearLayout>(Resource.Id.form_layout);
if (selectedItem.IsSelected)
{
selectedItem.IsSelected = false;
selectedFormLayout.SetBackgroundColor(Color.White);
formsListToDelete.Remove(selectedItem);
}
else
{
selectedItem.IsSelected = true;
selectedFormLayout.SetBackgroundResource(Resource.Drawable.Form_Border);
formsListToDelete.Add(selectedItem);
}
}
}
catch (Exception exception)
{
}
}
}
public class Form
{
private bool _isSelected;
public byte[] ImageResourceId { get; set; }
public string Heading { get; set; }
public string SubHeading { get; set; }
public string Caption { get; set; }
public string UpdatedFormDate { get; set; }
public string id { get; set; }
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
}
}
}
public class FormAdapter : BaseAdapter<Form>
{
private List<Form> formItems;
private Activity context;
public override Form this[int position]
{
get
{
return formItems[position];
}
}
public override int Count => formItems.Count;
public FormAdapter(List<Form> forms, Activity context) : base()
{
try
{
LoggingManager.Enter("ConstructorName:FormAdapter And ActivityName:FormsActivity");
this.context = context;
formItems = forms;
LoggingManager.Exit("ConstructorName:FormAdapter And ActivityName:FormsActivity");
}
catch (Exception exception)
{
LoggingManager.Error(exception, "FormAdapter", "FormAdapter", "FormsActivity");
}
}
public override int GetItemViewType(int position)
{
return position;
}
public override long GetItemId(int position)
{
try
{
return position;
}
catch (Exception exception)
{
return 0;
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
try
{
var form = formItems[position];
View view = convertView;
if (view == null)
view = context.LayoutInflater.Inflate(Resource.Layout.Forms_ChildLayout, null);
var imageBitMap = BitmapFactory.DecodeByteArray(form.ImageResourceId, 0, form.ImageResourceId.Length);
view.FindViewById<ImageView>(Resource.Id.form_Image).SetImageBitmap(imageBitMap);
view.FindViewById<TextView>(Resource.Id.heading).Text = form.Heading;
view.FindViewById<TextView>(Resource.Id.subHeading1).Text = form.SubHeading;
view.FindViewById<TextView>(Resource.Id.subHeading2).Text = form.Caption;
view.FindViewById<TextView>(Resource.Id.formupdateddatetime).Text = form.UpdatedFormDate;
return view;
}
catch (Exception exception)
{
LoggingManager.Error(exception, "GetView", "FormsActivity");
return null;
}
}
}
}
Обжигая, я узнал, что зритель должен использовать, но, будучи новичком в xamarin.android, я не совсем понимаю, как это сделать. Пожалуйста, помогите в решении этой проблемы.
Спасибо за ответ @ G.hakim, Подскажите, пожалуйста, как это решить.
By searching I came to know viewholder has to use, but being newbie in xamarin.android I am not really understanding how to do that
Вот и пытаюсь сделать для вас класс Holder. Это может вам помочь
Объявите класс FormHolder в том же файле FormAdapter со всеми элементами управления, которые есть в макете вашего элемента Forms_ChildLayout.
public class FormHolder : Java.Lang.Object
{
public ImageView Form_Image { get; set; }
public TextView Heading { get; set; }
public TextView SubHeading1 { get; set; }
public TextView SubHeading2 { get; set; }
public TextView Formupdateddatetime { get; set; }
}
Это будет FormAdapter вашего GetView
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView;
FormHolder holder = null;
if (view != null)
{
holder = view.Tag as FormHolder;
}
if (holder == null)
{
holder = new FormHolder();
view = context.LayoutInflater.Inflate(Resource.Layout.Forms_ChildLayout, parent, false);
holder.Form_Image = (ImageView)view.FindViewById(Resource.Id.form_Image);
holder.Heading = (TextView)view.FindViewById(Resource.Id.heading);
holder.SubHeading1 = (TextView)view.FindViewById(Resource.Id.subHeading1);
holder.SubHeading2 = (TextView)view.FindViewById(Resource.Id.subHeading2);
holder.Formupdateddatetime = (TextView)view.FindViewById(Resource.Id.formupdateddatetime);
holder.Form_Image.SetImageBitmap(imageBitMap);
holder.Heading.Text= form.Heading;
holder.SubHeading1.Text= form.SubHeading;
holder.SubHeading2.Text = form.Caption;
holder.Formupdateddatetime.Text = form.UpdatedFormDate;
}
return view;
}
Это способ сделать это, но есть другое решение - использовать RecyclerView. Я знаю, что ListView выполняет многие функции почти так же, как RecyclerView, но использование RecyclerView вынуждает вас использовать шаблон ViewHolder, и у вас больше никогда не будет этой проблемы. Я не говорю, что ваше решение неверно, потому что это определенно не так, но есть решение использовать RecyclerView :-)
@Darwind - Я согласен с вами, в этой конкретной ситуации RecyclerView был бы более точным. Это не смешивает элементы при прокрутке и более продвинуто, чем ListView.
Это потому, что метод getview вызывается после прокрутки, и, следовательно, первый выбор элемента также выбирает элемент 3