Мои требования : мне нужно анимировать 7 * 16 светодиодный дисплей, передавая кадры через приложение Android через BluetoothLE.Я создал дизайн дисплея в приложении и добавил к ним пустые виды с градиентным фоном.Цвет этих представлений должен измениться, когда мое касание перемещается в них.Добавление сенсорного прослушивателя к каждому представлению не поможет в моем случае.
Чего я достиг : у меня есть большое количество представлений (100+), добавленных программно с тегомустановить для каждого из них.Я установил обработчик событий OnTouch для родительского представления, в которое были добавлены эти представления.Отслеживая абсолютные координаты события касания (x и y) и сравнивая с абсолютными границами нескольких отдельных представлений, которые я зацикливаю в обработчике событий касания, я могу обнаруживать зависание, подобное движению касания (вне границ воценки) более 3-4 просмотров правильно.
Я сослался на решение из https://stackoverflow.com/a/21903640
Где я застрял : Однако, когда я пытаюсь увеличить размер цикла, чтобы охватить все добавленные виды,отклик приложения замедляется, и при наведении на большинство представлений происходит сбой.Я знаю, что это происходит из-за сложных вычислений в обработчике событий OnTouch, которые я не должен делать.
Что мне нужно : мне нужно улучшение этого решения с точки зрения производительности илиальтернативный способ достижения моей цели.
Фрагмент кода
void DrawScreen()
{
for (int column = 0; column < 8; column++)
{
for (int row = 0; row < 17; row++)
{
relativeLayout.AddView(DrawRect(row, column));
}
}
}
View DrawRect(int row, int column)
{
View customView = new View(Context);
GradientDrawable shape = new GradientDrawable();
shape.SetShape(ShapeType.Rectangle);
shape.SetCornerRadii(new float[] { 10, 10, 10, 10, 10, 10, 10, 10 });
shape.SetColor(Color.ParseColor("#3F0000"));
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);
param.LeftMargin = ((column-1) * (width + h_spacing)) + h_spacing;
param.Width = width;
param.Height = height;
param.TopMargin = ((row-1) * (height + v_spacing)) + v_spacing;
customView.Background = shape;
customView.LayoutParameters = param;
customView.Tag = (8 - column).ToString() + "," + (17 - row).ToString();
return customView;
}
private void RelativeLayout_Touch(object sender, View.TouchEventArgs e)
{
if(e.Event.Action == MotionEventActions.Up)
{
out_of_bounds = true;
view_in_bound = null;
}
else
{
for (int row = 1; row < 8; row++)
{
for (int column = 1; column < 17; column++)
{
View view = relativeLayout.FindViewWithTag(row.ToString() + "," + column.ToString());
if (CheckInterSection(view, e.Event.RawX, e.Event.RawY))
{
if (out_of_bounds == true)
{
view_in_bound = view;
out_of_bounds = false;
Log.Debug("Touch", "Inside");
//ToggleViewState(view);
}
else
{
Log.Debug("Touch", "Still Inside");
}
}
else
{
if (view == view_in_bound)
{
out_of_bounds = true;
view_in_bound = null;
Log.Debug("Touch", "Outside");
}
}
}
}
}
}
bool CheckInterSection(View view, float rawX, float rawY)
{
int[] location = new int[2];
view.GetLocationOnScreen(location);
int x = location[0] - h_spacing/2;
int y = location[1] - v_spacing/2;
int width = (view.Width + h_spacing/2);
int height = (view.Height + v_spacing/2);
return (!(rawX < x || rawX > (x + width) || rawY < y || rawY > (y + height)));
}