Xamarin.Androidで更新されたテキストを内部データに連携する方法(外部のMVVMなどを利用しない方法)
Xamarin.Androidで更新されたテキストを内部データに連携する方法
で、かなり詰まったので、同じ人がいないようにとの願いのメモです。
初心者なので、ご指摘あればいただけるとうれしいです。
最後に、クラス全体を載せていますので、説明が不要な方はそちらをご覧ください。
【手順】
- BeforeTextChangedでテキスト変更開始を検知
- TextChangedで変更することを確定させる
- AfterTextChangedで上記を満たした場合に、変更とみて更新を行う
※ただし、複数回流れることがあります。 - 保存時の動作
- フォーカスがある場合のみの保存とする(しないとなんかすごく更新がかかる。恐らくなんか実装が変)
- GetViewで保存した、EditTextに紐づけたタグ情報を元に対象のデータを特定
- 更新する。
- isEdittingはActivityで、保存ボタンを押したときにこのフラグを基準に1度のみ保存動作をさせるため指定
動作したAdapterのまとめです。
public class ListItemDetailAdapter : BaseAdapter<ViewArticleItem>
{
#region メンバ変数
private Activity _activity;
private List<ViewArticleItem> _items;
private DbContext dbContext;
/// <summary>
/// EditTextを変更したかどうか
/// </summary>
private bool isEditting = false;
#endregion#region 必須処理
public ListItemDetailAdapter(Activity activity, List<ViewArticleItem> items)
{
this._activity = activity;
this._items = items;
dbContext = Common.ConnectDB.GetDBContext();
}public override long GetItemId(int position) => position;
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView ?? _activity.LayoutInflater.Inflate(Resource.Layout.ListItemDetailLayout, null);//対応するプロパティの割り当て
EditText editText = view.FindViewById<EditText>(Resource.Id.editText);
ViewArticleItem item = _items[position];
editText.Text = item.Text;
setTagItemId(editText, item.ItemId);
SetEditEvent(editText);return view;
}public override int Count => _items.Count;
public override ViewArticleItem this[int position] => throw new NotImplementedException();#endregion
#region タグ:ItemIdを設定する
private void setTagItemId(EditText editText, int itemId)
{
editText.SetTag(Resource.Id.editText, itemId);
}private int getTagItemId(EditText editText)
{
return (int)editText.GetTag(Resource.Id.editText);
}#endregion
#region イベント処理
private void SetEditEvent(EditText editText)
{
//重複しないようにイベント削除
editText.TextChanged -= EditTextOnTextChanged;
editText.BeforeTextChanged -= EditTextOnBeforeTextChanged;
editText.AfterTextChanged -= TextViewOnAfterTextChanged;
editText.FocusChange -= EditTextOnFocusChange;//イベント再登録
editText.TextChanged += EditTextOnTextChanged;
editText.BeforeTextChanged += EditTextOnBeforeTextChanged;
editText.AfterTextChanged += TextViewOnAfterTextChanged;
editText.FocusChange += EditTextOnFocusChange;
}/// <summary>
/// フォーカスが変わった場合
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void EditTextOnFocusChange(object sender, View.FocusChangeEventArgs e)
{
if (isEditting)
{
//変更時にデータを保存する
dbContext.SaveViewArticleItems(GetArticleItems());
DebugMessage.ShowDebugToastShort(Application.Context, "Itemsを保存しました");isEditting = false;
}
}private bool isChange = false;
private bool isChanging = false;
private void EditTextOnBeforeTextChanged(object sender, TextChangedEventArgs e)
{
if (isChange == false)isChange = true;
}
private void EditTextOnTextChanged(object sender, TextChangedEventArgs e)
{
if (isChange && e.BeforeCount != e.AfterCount)isChanging = true;
}/// <summary>
/// 文字変更入力後処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextViewOnAfterTextChanged(object sender, AfterTextChangedEventArgs e)
{
if (false == (isChange && isChanging))return;//描画中の文字に更新文字を設定する
SaveChangeText((EditText)sender);isChange = false;
isChanging = false;}
#endregion
#region 外部利用処理
public List<ViewArticleItem> GetArticleItems()
{
return _items;
}#endregion
#region 内部処理
/// <summary>
/// 変更を保持データに反映する
/// </summary>
/// <param name="editText">変更データを持つEditText</param>
private void SaveChangeText(EditText editText)
{
if (editText.HasFocus == false) return;//これがないと、アクション時などに、一覧表が更新されてしまう//更新対象を特定するために、ItemIdを取得する
var itemId = getTagItemId(editText);//データに反映する
var item = _items.First(x => x.ItemId == itemId);
item.Text = editText.Text;
isEditting = true;
}#endregion
}
Visual Studio かっこの色を階層ごとにそろえる
本日、TwitterでVSCodeで鍵かっこで、色をそろえる、拡張機能があるというのを見て、すごくいい! と思った。
Bracket Pair Colorizer - Visual Studio Marketplace
そのツイートにVisualStudio版の名前 Viasforaが乗っていてさっそく入れた。
が、すごく残念なことに、かっこ以外の色も変わるため、とってもカラフルになりすぎて、エラーなのか、階層なのかさパリわからなくなってしまった。 設定いじってどうにかできないか試行錯誤…
背景が黒の場合、の設定ができたので、自分用にアップしておく もっといい設定があったら知りたいな
Xamarin.AndroidのListViewで下線を削除する
調べても適切なのが見つからなかったので…
一般的にonCreateで生成される場合に、ListViewを取得すると思うのでその直後で変更してあげれば問題が無かった
初期宣言
private ListView mainListView;
バインド
mainListView = FindViewById
(Resource.Id.listView1);
下線削除
mainListView.DividerHeight = 0;
戻すときは以下を変数に保存しておく(型:Android.Graphics.Drawables.GradientDrawable)
(GradientDrawable)mainListView.Divider
以上です。 私と同じ苦しみの方の目に留まれば幸いです。
Xamarin.AndroidでSQLiteの中身を確認する
以下の方法でもよいですが、より良い方法に出会いました。
生成したSqliteのファイルをDropboxに上げる方法が、バージョンに依存せずに利用できるため、良いと考えております。
気になる方はどうブログの別記事をご参照ください。
確認環境
VisualStudio 2017 15.7.5
Androidエミュレータ
デフォルトの KitKat4.4
※以下のコピーはOreo8.0で確認したところPermissionErrorでしたのでご注意ください。(自分がはまった)
ツール
→Android
→Android adb コマンドプロンプト
コマンド
コマンド | 意味 |
-e | エミュレータへコマンドを送る |
-d | 端末にコマンドを送る |
-s | 端末指定 |
--help | ヘルプ |
https://developer.android.com/studio/command-line/adb?hl=ja
SQLiteBackUp
コピーコマンド
run-as プロジェクト名 cat file/DB名.db3 > /sdcard/DB名.db3
Windowsへの配置コマンド
adb -e pull sdcard/DB名.db3 d:\AndroidDebug
情報がいろいろあって、自分の環境に合うのが見つからなかったので作成。
以下、コマンドのまとめ。
adb -e shell
run-as プロジェクト名 cat file/DB名.db3 > /sdcard/DB名.db3
exit
adb -e pull sdcard/DB名.db3 d:\AndroidDebug
※AndroidDebugはコピー先のフォルダ名(適当)
VisualStudioタブ設定
忘れてしまっていたのでメモ
タブのピン(Pin)を別の行で表示する設定
ツール
→オプション
→環境
→タブとウィンドウ
→固定されたタブ
→固定されたタブを別の行で表示する
MvvmCrossのVisualStudioでの利用に関して
xamarinネイティブによるモバイルアプリ開発 c#によるandroid/ios ui制御の基礎
を読んでいると、MvvmCrossの利用のところで詰まったので、その補助としてブログを書きます。
まずはじめに、書いてある通りやってもファイルがないとか色々言われてできません。できませんでしたorz
ちなみに、以下を入れてもできませんでした・・・つらい
なので、以下をお試しください。
VisualStudioでの拡張機能より以下の四つをインストールする
・MvvmCross for Visual Studio(2.0以上)
・MvvmCross for Visual Studio(1.5.6)
・MVXTemplates
MvvmCross for Visual Studio
二種類ありますが、それぞれ違うみたいです。
1.5.6が今回の書籍のものに一番近いと思います。
2.0以上はマルチページとシングルページなのでもう少し学習してからかと思っています。(この記事の筆者はXamarin初心者なのでよく分からないです)
MVXTemplates
これは、インテリセンスの補強のためなので念のため入れておくことをおすすめします。
以上となります。
私と同様の引っかかりを他の人が得ないことを願います。