雷って幻想的だよね?

宗教:C#、ラノベ好きの戯言です。※Google Analytics 埋め込みを利用しています。

Xamarin.Androidで更新されたテキストを内部データに連携する方法(外部のMVVMなどを利用しない方法)

Xamarin.Androidで更新されたテキストを内部データに連携する方法
で、かなり詰まったので、同じ人がいないようにとの願いのメモです。

初心者なので、ご指摘あればいただけるとうれしいです。

最後に、クラス全体を載せていますので、説明が不要な方はそちらをご覧ください。

【手順】

  1. BeforeTextChangedでテキスト変更開始を検知
  2. TextChangedで変更することを確定させる
  3. AfterTextChangedで上記を満たした場合に、変更とみて更新を行う
    ※ただし、複数回流れることがあります。
  4. 保存時の動作
    1. フォーカスがある場合のみの保存とする(しないとなんかすごく更新がかかる。恐らくなんか実装が変)
    2. GetViewで保存した、EditTextに紐づけたタグ情報を元に対象のデータを特定
    3. 更新する。
    4. 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 かっこの色を階層ごとにそろえる

本日、TwitterVSCodeで鍵かっこで、色をそろえる、拡張機能があるというのを見て、すごくいい! と思った。

Bracket Pair Colorizer - Visual Studio Marketplace

そのツイートにVisualStudio版の名前 Viasforaが乗っていてさっそく入れた。

が、すごく残念なことに、かっこ以外の色も変わるため、とってもカラフルになりすぎて、エラーなのか、階層なのかさパリわからなくなってしまった。 設定いじってどうにかできないか試行錯誤…

背景が黒の場合、の設定ができたので、自分用にアップしておく もっといい設定があったら知りたいな

Dropbox - 拡張機能Viasfora - Simplify your life

Xamarin.Androidで想定外の動作をした時にすること

もし、仮に、これを見た人がいたら気に留めていただきたいことを記述させていただきます。

Xamarin.Androidを開発していて、実装とエミュレーターの動作が違った場合、ソースコードを戻す前にしていただきたいことがあります。

それは

エミュレーターAndroidの再起動です。

私は、はまりました。(T-T)

画面表示の右側の電源ボタンを長押しするとReStartが表示されます。

これを行って、端末を再起動してください。

私の場合は、クリック関連のイベントがイメージ通りにいかなかったのでソース戻しましたが、再起動したところ、治りました。

同じ悲しみを負う方が少ないことを祈ります。

orz

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はコピー先のフォルダ名(適当)

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

これは、インテリセンスの補強のためなので念のため入れておくことをおすすめします。


以上となります。
私と同様の引っかかりを他の人が得ないことを願います。