Некоторые дополнительные детали, чтобы пролить свет на оригинальный пост:
трех основных файлов, которые мы используем для рендеринга клавиатуры являются KeyboardView.cs , KeyboardRowView.cs и KeyView.cs.
KeyboardView (контейнер для всей клавиатуры)
Это не имеет никаких проблем рендеринга. KeyboardView простирается LinearLayout
и его OnDraw
работает метод, вызывая Build()
функцию, чтобы создать то, что ему нужно (только базовый фон, который будет «держать» отдельные клавиши):
protected override void OnDraw(Canvas canvas)
{
Build();
base.OnDraw(canvas);
// background
Paint bg = new Paint(PaintFlags.AntiAlias);
bg.Color = BG; // light blue
canvas.DrawRect(0, 0, MeasuredWidth, Height, bg);
InvalidateKeys();
}
(... и Build()
ниже. ..)
public void Build()
{
// only build once
if (keyLayout != null)
return;
// clear out children
RemoveAllViews();
// define sizes of stuff
if (isPortrait)
{
keyMargin = (int)(MeasuredWidth * .01f);
}
else
{
keyMargin = (int)(MeasuredHeight * .01f);
}
keyWidth = (MeasuredWidth - (keyMargin * 2))/keyboard.MaxCols;
keyHeight = (MeasuredHeight - (keyMargin * 2))/keyboard.Rows.Count;
// set general padding around keyboardview
SetPadding(keyMargin, keyMargin, keyMargin, keyMargin);
// build KeyLayout from the keyboard object
keyLayout = new List<List<KeyView>>();
int idx = 0;
foreach (List<Key> row in keyboard.Rows)
{
keyLayout.Add(new List<KeyView>());
// create and add new KeyboardRowView
KeyboardRowView krv = new KeyboardRowView(Context, this, idx);
AddView(krv);
// figure out if we need a margin offset for this row
int extraMargin = 0;
int numCols = CountRowCols(row);
if (numCols < keyboard.MaxCols)
{
// measure full width of the button container and the total row margin
int rowWidth = (int)(numCols * keyWidth);
int rowMargin = MeasuredWidth - (keyMargin * 2) - rowWidth;
// add the offset
extraMargin = rowMargin/2;
}
// build keys and add them to keyLayout and KeyboardRowView
int idx2 = 0;
foreach (Key key in row)
{
int leftMargin = idx2 == 0 ? extraMargin : 0;
KeyView kv = new KeyView(Context, this, key, leftMargin);
keyLayout[idx].Add(kv);
krv.AddView(kv);
idx2++;
}
idx++;
}
}
(как дружественное напоминание, что мы делаем это, потому что мы нужны пользовательские клавиатуры, которая может отображать только определенные ключи/команды для наших пользователей.)
KeyboardRowView (контейнер для каждой строки ключей)
Это также распространяется на LinearLayout
, а также способ его OnDraw
называется:
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint();
paint.SetARGB(255, 0, 0, 0);
paint.SetStyle(Paint.Style.Stroke);
paint.StrokeWidth = 3;
canvas.DrawRGB(255, 255, 255);
canvas.DrawRect(0, 0, 100, 100, paint);
}
KeyView (класс который загружает и отображает каждый отдельный ключ)
KeyView расширяет View
и View.IOnTouchListener
.Конструктор KeyView, называется, но его метод OnDraw
никогда не вызывается/казнены:
// key views are always dynamically created
public KeyView(Context ctx, KeyboardView parent, Key k, int leftMargin)
: base(ctx)
{
// make sure the key will draw
SetWillNotDraw(false);
keyboard = parent;
key = k;
isDown = false;
// check for an overridden span to adjust width, if needed
int span = string.IsNullOrEmpty(key.Span) ? 1 : Convert.ToInt32(key.Span);
int keyWidth = keyboard.keyWidth + ((span - 1) * keyboard.keyWidth);
width = keyWidth;
height = keyboard.keyHeight;
// set margin
var parameters = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WrapContent,
LinearLayout.LayoutParams.MatchParent
);
parameters.LeftMargin = leftMargin;
LayoutParameters = parameters;
// set touch listener
SetOnTouchListener(this);
// enable haptic feedback for button presses
HapticFeedbackEnabled = true;
}
(... и OnDraw)
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
KeyState primary = key.Primary;
KeyState secondary = key.Secondary;
if (keyboard.swapped)
{
primary = key.Secondary != null ? key.Secondary : key.Primary;
secondary = key.Secondary != null ? key.Primary : null;
}
if (keyboard.shifted)
{
if (primary.Shift != null)
primary = primary.Shift;
if (secondary != null && secondary.Shift != null)
secondary = secondary.Shift;
}
// figure out what color the key is supposed to be
Paint bg = new Paint(PaintFlags.AntiAlias);
bg.Color = GetKeyBgColor(key.Style);
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
canvas.DrawRoundRect(keyboard.keyMargin, keyboard.keyMargin, width - keyboard.keyMargin, height - keyboard.keyMargin, keyboard.keyMargin, keyboard.keyMargin, bg);
else
canvas.DrawRoundRect(new RectF(keyboard.keyMargin, keyboard.keyMargin, width - keyboard.keyMargin, height - keyboard.keyMargin), keyboard.keyMargin, keyboard.keyMargin, bg);
// draw primary key state
Paint fg = new Paint(PaintFlags.AntiAlias);
fg.TextSize = height * .5f;
fg.Color = GetKeyFgColor(key.Style);
string character = string.IsNullOrEmpty(primary.Character) ? "#" : primary.Character;
int charWidth = Convert.ToInt32(fg.MeasureText(character));
int charX = (width - charWidth)/2;
canvas.DrawText(character, charX, (height * .7f), fg);
// draw secondary key state
if (secondary != null)
{
fg.TextSize = height * .25f;
fg.Color = GetKeyFgColor(key.Style, true);
character = string.IsNullOrEmpty(secondary.Character) ? "#" : secondary.Character;
charWidth = Convert.ToInt32(fg.MeasureText(character));
charX = width - charWidth - (keyboard.keyMargin * 2);
canvas.DrawText(character, charX, (height * .35f), fg);
}
}
Я смущен. Оба KeyboardView и KeyboardRowView имеют вызов функции SetWillNotDraw(false);
в своих конструкторах/методах инициализации. KeyView также имеет тот же вызов функции и успешно получает каждое значение ключа, которое необходимо визуализировать. То, чего я не понимаю, это то, почему он просто ... не ... рисует ... клавиатуру. (Argh.) Когда я поговорил с оригинальным плакатом об этом, он сказал мне, что все условия выполнены для того, чтобы клавиши клавиатуры были визуализированы. Я попытался установить точки останова, чтобы увидеть, что мешает KeyView's OnDraw
быть вызванным, но попал в повторные вызовы функций OnMeasure
(и есть много ключей, которые получают визуализированы, чтобы получить старое быстро).
Стоит отметить, что мы тестировали его на последнем Nexus 6P смартфон (работает фондовый Android 6,0 Зефир) и старый Motorola Droid 4 (с Зефир установлен с помощью CyanogenMod 13). Когда мы пытались его с помощью эмулятора Xamarin Android Player (работает Зефир), он на самом деле работал ... я думаю, что эмулятор может быть оказание помощи клавиатуры без проблем, потому что сами фактические телефоны либо
(а) ограничение доступа как-то
(б) потенциально держась старого кода, и мы просто не полностью удалены старые .apks
(с) какой-либо другой вопрос, который я не думал о
Thank вы для своего времени. Если кто-то может подумать о возможном направлении, чтобы войти, это было бы оценено!
В основном вы спрашиваете: «Почему мой код не работает», без предоставления каких-либо. Это будет трудно для кого-то угадать, что происходит. Глядя на трекеры по проблеме, я не вижу, чтобы кто-то имел проблемы с вещами, которые не рисовали. – Cheesebaron
Я предоставил код в нижней части сообщения. –