扩展标题:
Sum {getSum = 0}
来填充Adapter
。ListView
这一行来填充RecyclerView
,其中每行包含一个
ListView
和2x Imageview
。当我点击一行的任何地方时,我需要在活动本身内触发Textview
事件,以便我可以做类似的事情
ItemSelected
我用过的答案:
Not able to fire the ListVIew Item click event when there is UI Control like Button in xamarin - 建议设置:
mListView.ItemSelected += (sender, e) =>
{
System.Diagnostics.Debug.Write("LISTVIEW CLICKED AT : " + e.Position);
//Once I know the row position, I can do the rest.
};
在这个答案Unable to get listView.ItemClick to be called in MonoDroid中,答案的简短引用显示
“问题是我在ListView中的ImageButton。它 正在窃取焦点并消耗触摸事件。“
LilMoke的解决方案是在他希望触发"Focusable = false" //on any element in the row
事件的行中设置每个元素的以下属性:
ItemSelected
似乎很好,这导致了后来的建议:
放
imageButton.Focusable = false;
imageButton.FocusableInTouchMode = false;
imageButton.Clickable = true;
imageButton.Click += (sender, args) => Console.WriteLine("ImageButton {0} clicked", position);
假设您的RecycleView的根元素是LinearLayout ,则在您的LinearLayout中
因为Android不允许任何项目在android:descendantFocusability="blocksDescendants"
中具有焦点。一个更简洁的版本,可以防止行项获得焦点。问题是在实现这个之后,我仍然无法触发ListView
事件。
我尝试过一个凌乱的解决方法:
1)
我尝试从ItemSelected
模板的声明中抓取并设置每个元素的Focusable
和Clickable
属性,但这很麻烦,不允许我访问StartActivity函数,它是一部分任何直接从Activity继承的类。
因为这是一个适配器,它继承自BaseAdapter<>代替。
我以前的问题一直被嘲笑,但在阅读完this之后,我正试图改变我的邪恶方式。
以下是与我所描述的相关的代码,应该更好地说明情况:
row.axml
RecyclerView
listContacts.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:weightSum="100"
android:descendantFocusability="blocksDescendants"
android:background="#F1F1F1">
<ImageView
android:id="@+id/imgPic"
android:src="@drawable/ic_action_person"
android:layout_width="0dp"
android:layout_weight="25"
android:layout_height="wrap_content"
android:background="#3B5998"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="65">
<TextView
android:id="@+id/txtName"
android:text="Contact Name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="65"
android:gravity="center"
android:textSize="18sp"
android:textColor="#000" />
<TextView
android:id="@+id/txtNumber"
android:text="(555)-444-2222"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="65"
android:gravity="center"
android:textSize="18sp"
android:textColor="#000" />
</LinearLayout>
<ImageButton
android:layout_width="50dp"
android:layout_height="wrap_content"
android:src="@drawable/xiconsmall"
android:id="@+id/btnDeleteAlbum" />
</LinearLayout>
ListContacts.cs
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:layout_width="match_parent"
android:layout_height="500dp"
android:visibility="visible"
android:id="@+id/listView"
android:fastScrollAlwaysVisible="true"
android:fastScrollEnabled="true"
android:smoothScrollbar="true"
android:clickable="true" />
<Button
android:text="Button"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnAdd" />
</LinearLayout>
</ScrollView>
ContactListAdapter.cs
namespace MainMobileDevProject
{
[Activity(Label = "Display row items", MainLauncher = true, Icon = "@drawable/xs")]
//public class ListContacts: AppCompatActivity
public class ListContacts : Activity
{
private ListView mListView;
private BaseAdapter<Contact> mAdapter;
private List<Contact> mContacts;
private ImageView mSelectedPic;
private Button mBtnAddPics, button;
public List<byte[]> imagesByteList = new List<byte[]>();
public List<string> imagesTagsList = new List<string>();
Bitmap myBitmap;
private ImageView _imageView;
public static class App
{
public static File _file;
public static File _dir;
public static Bitmap bitmap;
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.listContacts);
string text = Intent.GetStringExtra("MyData") ?? "Data not available";
System.Diagnostics.Debug.Write("DATA WE PASSED HERE IS : " + text);
mListView = FindViewById<ListView>(Resource.Id.listView);
mContacts = new List<Contact>();
mBtnAddPics = FindViewById<Button>(Resource.Id.btnAdd);
//mAdapter = new ContactListAdapter(this, Resource.Layout.pager_item, mContacts, action);
mAdapter = new ContactListAdapter(this, Resource.Layout.row_contact, mContacts);
//having an issue with my list adapter
//none of my event items such as click or itemselected will fire
//debug log aren't even firing, the proposed solution is to set each row's child elements to have a value of
//false for "focusable", and a better solution again is to set the root of the row's layout to have
// an attribute of android:descendantFocusability="blocksDescendants". this can be seen in row_contact.axml
//the problem though is that now the row's contents can be accessed, but not from this module, but only in the adapter, which makes things messy of course, but I haven't been able to start a new activity
// due to my adapter(ContactListAdapter.cs) inheriting from the BaseAdapter class
mListView.ItemClick += lv_ItemClick;
void lv_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
//not firing
System.Diagnostics.Debug.Write("LISTVIEW CLICKED AT : " + e.Position);
}
mListView.Adapter = mAdapter;
//mListView.NotifyDataSetChanged();
mListView.ItemSelected += (sender, e) =>
{
System.Diagnostics.Debug.Write("LISTVIEW CLICKED AT : " + e.Position);
};
mListView.ItemClick += (sender, e) =>
{
System.Diagnostics.Debug.Write("LISTVIEW CLICKED AT : " + e.Position);
};
mAdapter.NotifyDataSetChanged();
}
private void MListView_ItemClick(object sender, ItemClickEventArgs e)
{
System.Diagnostics.Debug.Write("myBitmap row id : " + e.Id);
System.Diagnostics.Debug.Write("myBitmap row parent is : " + e.Parent);
System.Diagnostics.Debug.Write("myBitmap row position : " + e.Position);
System.Diagnostics.Debug.Write("myBitmap row view : " + e.View);
}
private void MBtnAddPics_Click(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection("Server=someawsconstring.something.eu-west-1.rds.amazonaws.com;Port=3307;database=ichangedthis;User Id=ichangedthis;Password=ichangedthis;charset=utf8");
//List<string> imageslist = new List<string>();
//List<byte[]> imageslist = new List<byte[]>();
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
System.Diagnostics.Debug.Write("CONN OPEN");
//string query = "SELECT * FROM tblUserAlbumPhoto HAVING UserID = '" + Intent.GetStringExtra("UsersID") + "' AND AlbumID = '" + Intent.GetStringExtra("UsersID") +"'";
string query = "SELECT * FROM tblUserAlbumPhoto HAVING UserID = '" + 1 + "' AND AlbumID = '" + 1 +"'";
MySqlCommand cmd = new MySqlCommand(query, con);
System.Diagnostics.Debug.Write("TRYING TO READ");
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
imagesByteList.Add(Convert.FromBase64String(dataReader.GetString(4)));
imagesTagsList.Add(dataReader.GetString(5));
//System.Diagnostics.Debug.Write("image still as base64 string is : " + dataReader.GetString(1));
//System.Diagnostics.Debug.Write("image converted from base64 found is : " + Convert.FromBase64String(dataReader.GetString(1)));
}
System.Diagnostics.Debug.Write("image ID found is : " + imagesByteList[0]);
System.Diagnostics.Debug.Write("image ID found is : " + imagesByteList[1]);
}
}
catch (MySqlException ex)
{
}
finally
{
con.Close();
System.Diagnostics.Debug.Write("CONN CLOSED");
System.Diagnostics.Debug.Write("image ID count found is : " + imagesByteList.Count);
}
CountImagesList();
if (imagesByteList.Count > 0) //just a test
{
CreateImgFromBytes(imagesByteList, imagesTagsList);
}
}
private void CreateImgFromBytes(List<byte[]> imageslist, List<string> tags)
{
//foreach(byte[] ba in imageslist)
for(int y=0;y<imagesByteList.Count;y++)
{
mContacts.Add(new Contact() { Name = tags[y], Image = imageslist[y] });
}
//mContacts.Add(new Contact() { Name = "abc", Number = "def", Image = imageslist[0] });
System.Diagnostics.Debug.Write("imageslist lentth is: " + imageslist.Count);
mAdapter.NotifyDataSetChanged();
//Decode with InJustDecodeBounds = true to check dimensions
//Stream stream = ContentResolver.OpenInputStream(data);
//BitmapFactory.Options options = new BitmapFactory.Options();
//options.InJustDecodeBounds = true;
//BitmapFactory.DecodeStream(stream);
////Calculate InSamplesize
//options.InSampleSize = CalculateInSampleSize(options, requestedWidth, requestedHeight);
////Decode bitmap with InSampleSize set
//stream = ContentResolver.OpenInputStream(data); //Must read again
//options.InJustDecodeBounds = false;
//Bitmap bitmap = BitmapFactory.DecodeStream(stream, null, options);
//return bitmap;
}
public void CountImagesList()
{
System.Diagnostics.Debug.Write("imageslist lentth is: " + imagesByteList.Count);
}
private void PicSelected(ImageView selectedPic)
{
mSelectedPic = selectedPic;
Intent intent = new Intent();
intent.SetType("image/*");
intent.SetAction(Intent.ActionGetContent);
this.StartActivityForResult(Intent.CreateChooser(intent, "Selecte a Photo"), 0);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
//if (resultCode == Result.Ok)
//{
// Stream stream = ContentResolver.OpenInputStream(data.Data);
// mSelectedPic.SetImageBitmap(DecodeBitmapFromStream(data.Data, 150, 150));
//}
Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
Uri contentUri = Uri.FromFile(App._file);
mediaScanIntent.SetData(contentUri);
SendBroadcast(mediaScanIntent);
// Display in ImageView. We will resize the bitmap to fit the display.
// Loading the full sized image will consume to much memory
// and cause the application to crash.
int height = Resources.DisplayMetrics.HeightPixels;
int width = _imageView.Height;
App.bitmap = App._file.Path.LoadAndResizeBitmap(width, height);
System.Diagnostics.Debug.Write("APP . BITMAP IS :: " + App.bitmap);
if (App.bitmap != null)
{
_imageView.SetImageBitmap(App.bitmap);
myBitmap = App.bitmap;
//App.bitmap = null;
}
// Dispose of the Java side bitmap.
GC.Collect();
}
private void CreateDirectoryForPictures()
{
App._dir = new File(
Environment.GetExternalStoragePublicDirectory(
Environment.DirectoryPictures), "Base64Attempt");
if (!App._dir.Exists())
{
App._dir.Mkdirs();
}
}
private bool IsThereAnAppToTakePictures()
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
IList<ResolveInfo> availableActivities =
PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
return availableActivities != null && availableActivities.Count > 0;
}
private void TakeAPicture(object sender, EventArgs eventArgs)
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
App._file = new File(App._dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid()));
intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file));
StartActivityForResult(intent, 0);
}
private Bitmap DecodeBitmapFromStream(Android.Net.Uri data, int requestedWidth, int requestedHeight)
{
//Decode with InJustDecodeBounds = true to check dimensions
System.IO.Stream stream = ContentResolver.OpenInputStream(data);
BitmapFactory.Options options = new BitmapFactory.Options();
options.InJustDecodeBounds = true;
BitmapFactory.DecodeStream(stream);
//Calculate InSamplesize
options.InSampleSize = CalculateInSampleSize(options, requestedWidth, requestedHeight);
//Decode bitmap with InSampleSize set
stream = ContentResolver.OpenInputStream(data); //Must read again
options.InJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.DecodeStream(stream, null, options);
return bitmap;
}
private int CalculateInSampleSize(BitmapFactory.Options options, int requestedWidth, int requestedHeight)
{
//Raw height and widht of image
int height = options.OutHeight;
int width = options.OutWidth;
int inSampleSize = 1;
if (height > requestedHeight || width > requestedWidth)
{
//the image is bigger than we want it to be
int halfHeight = height / 2;
int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > requestedHeight && (halfWidth / inSampleSize) > requestedWidth)
{
inSampleSize *= 2;
}
}
return inSampleSize;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.actionbar_home, menu);
return base.OnCreateOptionsMenu(menu);
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.add:
CreateContactDialog dialog = new CreateContactDialog();
FragmentTransaction transaction = FragmentManager.BeginTransaction();
//Subscribe to event
dialog.OnCreateContact += dialog_OnCreateContact;
dialog.Show(transaction, "create contact");
return true;
default:
return base.OnOptionsItemSelected(item);
}
}
void dialog_OnCreateContact(object sender, CreateContactEventArgs e)
{
mContacts.Add(new Contact() { Name = e.Name, Number = e.Number });
mAdapter.NotifyDataSetChanged();
}
}
/*
public static class BitmapHelpers
{
public static Bitmap LoadAndResizeBitmap(this string fileName, int width, int height)
{
// First we get the the dimensions of the file on disk
BitmapFactory.Options options = new BitmapFactory.Options { InJustDecodeBounds = true };
BitmapFactory.DecodeFile(fileName, options);
// Next we calculate the ratio that we need to resize the image by
// in order to fit the requested dimensions.
int outHeight = options.OutHeight;
int outWidth = options.OutWidth;
int inSampleSize = 1;
if (outHeight > height || outWidth > width)
{
inSampleSize = outWidth > outHeight
? outHeight / height
: outWidth / width;
}
// Now we will load the image and have BitmapFactory resize it for us.
options.InSampleSize = inSampleSize;
options.InJustDecodeBounds = false;
Bitmap resizedBitmap = BitmapFactory.DecodeFile(fileName, options);
return resizedBitmap;
}
}
*/
}
这是我上面描述的凌乱的解决方法,无法继续使用它
namespace MainMobileDevProject
{
class ContactListAdapter : BaseAdapter<Contact>
{
private Context mContext;
private int mLayout;
private List<Contact> mContacts;
private Action<ImageView> mActionPicSelected;
public ContactListAdapter(Context context, int layout, List<Contact> contacts, Action<ImageView> picSelected)
{
mContext = context;
mLayout = layout;
mContacts = contacts;
mActionPicSelected = picSelected;
}
public ContactListAdapter(Context context, int layout, List<Contact> contacts)
{
mContext = context;
mLayout = layout;
mContacts = contacts;
}
public override Contact this[int position]
{
get { return mContacts[position]; }
}
public override int Count
{
get { return mContacts.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
//row.notif
if (row == null)
{
row = LayoutInflater.From(mContext).Inflate(mLayout, parent, false);
}
row.FindViewById<TextView>(Resource.Id.txtName).Text = mContacts[position].Name;
row.FindViewById<TextView>(Resource.Id.txtNumber).Text = mContacts[position].Number;
ImageView pic = row.FindViewById<ImageView>(Resource.Id.imgPic);
row.Clickable = true;
if (mContacts[position].Image != null)
{
pic.SetImageBitmap(BitmapFactory.DecodeByteArray(mContacts[position].Image, 0, mContacts[position].Image.Length));
}
if (mContacts[position].Image == null)
{
//here we should replace mcontacts[position] with imageslist[position], then it'll at least pull
//the 2 byte[] images we have
//pic.SetImageBitmap(BitmapFactory.DecodeByteArray(mContacts[position].Image, 0, mContacts[position].Image.Length));
//pic.SetImageBitmap(BitmapFactory.DecodeByteArray(mContacts[position].Image, 0, mContacts[position].Image.Length));
}
//var imageButton = row.FindViewById<ImageView>(Resource.Id.imgPic);
//imageButton.Focusable = false;
//imageButton.FocusableInTouchMode = false;
//imageButton.Clickable = true;
var removeButton = row.FindViewById<ImageButton>(Resource.Id.btnDeleteAlbum);
removeButton.Focusable = false;
removeButton.FocusableInTouchMode = false;
removeButton.Clickable = true;
//imageButton.Click += (sender, args) =>
//{
// System.Diagnostics.Debug.Write("myBitmap row id :AAAAAAAAAAAAAAAAAAAA ");
// Console.WriteLine("ImageButton {0} clicked", position);
//};
removeButton.Click += (sender, args) =>
{
System.Diagnostics.Debug.Write("myBitmap row id :AAAAAAAAAAAAAAAAAAAA ");
Console.WriteLine("RemoveButton {0} clicked", position);
};
//pic.Click -= pic_Click;
pic.Click += (object sender, EventArgs e) =>
{
MySqlConnection con = new MySqlConnection("Server=db4free.net;Port=3307;database=ofsligodb;User Id=ofoley1;Password=pinecone;charset=utf8");
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
System.Diagnostics.Debug.WriteLine("CONNECTION OPEN*****: ");
MySqlCommand Readcmd = new MySqlCommand("DELETE FROM tblUserAlbumPhoto WHERE UserID = '" + 1 + "' AND " +
"AlbumID = '" + 1 + "' and ID = '" + position + "'");
Readcmd.Connection = con;
Readcmd.ExecuteNonQuery();
System.Diagnostics.Debug.WriteLine("DELETE SHOULD HAVE HAPPENED*****: ");
}
}
catch (MySqlException ex)
{
//mTxtImgChoiceInfo.Text = ex.ToString();
}
finally
{
con.Close();
System.Diagnostics.Debug.WriteLine("CONN CLOSED*****: ");
}
};
return row;
}
void pic_Click(object sender, EventArgs e)
{
//Picture has been clicked
System.Diagnostics.Debug.Write("YOU CLICKED ME AND THE ROW INDEX WAS : " + e.position);
}
}
}
。 任何含糊不清/混淆请告诉我。 如果重复请请解释原因,谢谢。
答案 0 :(得分:0)
据我了解,您需要在适配器的每个row
添加OnClick。