Android : Google Gson と Data Binding ( include される画面定義 とバインドの継承 )
|
|
日時: 2015/10/27 10:21
名前: lightbox
|
拡張子:
import android.databinding.BaseObservable;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.NumberPicker;
import android.widget.Spinner;
import java.util.Arrays;
public class Syain extends BaseObservable {
// シリアライズ・デシリアライズをしない( static )
static public MainActivity context = null;
// NumberPicker 用
static public NumberPicker np = null;
static public String[] nums = {"男性","女性","不明"};
static public int[] values = {-10,20,100};
// Spinner 用
static public Spinner sp = null;
// DatePicker 用
static public DatePicker dp = null;
public String scode;
public String kj;
public String furi;
public String syozoku;
public String seibetu;
public String kyuyo;
public String teate;
public String kanri;
public String birth;
public String sname;
public Syain() {
this.scode = "";
this.kj = "初期状態";
this.furi = "";
this.syozoku = "";
this.seibetu = "";
this.kyuyo = "";
this.teate = "";
this.kanri = "";
this.birth = "";
this.sname = "";
}
// ******************************************
// NumberPicker 用
// ******************************************
public void setupSeibetuControl() {
np.setMinValue(0);
np.setMaxValue(2);
np.setDisplayedValues(nums);
np.setValue(1);
}
public void setSeibetuControl(String seibetu) {
if ( seibetu != null ) {
this.seibetu = seibetu;
}
np.setValue(Integer.parseInt(this.seibetu));
}
public void getSeibetuControl() {
this.seibetu = Integer.toString(np.getValue());
}
// ******************************************
// Spinner 用
// ******************************************
public void setupSyozokuControl(String[] list_data) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
context,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.addAll(list_data);
sp.setAdapter(adapter);
}
public void setSyozokuControl(String syozoku,String[] list_value) {
if ( syozoku != null ) {
this.syozoku = syozoku;
}
int idx = Arrays.binarySearch(list_value,this.syozoku);
sp.setSelection(idx);
}
public void getSyozokuControl(String[] list_value) {
int idx = sp.getSelectedItemPosition();
this.syozoku = list_value[idx];
}
// ******************************************
// DatePicker 用
// ******************************************
public void setupBirthControl(Boolean spinners, Boolean calendar) {
dp.setSpinnersShown(spinners);
dp.setCalendarViewShown(calendar);
}
public void setBirthControl(String birth) {
if ( birth != null ) {
this.birth = birth;
}
if ( this.birth != null ) {
String dt[] = this.birth.split("-");
if ( dt.length == 3 ) {
dp.updateDate(Integer.parseInt(dt[0]), Integer.parseInt(dt[1])-1, Integer.parseInt(dt[2]));
}
}
}
public void getBirthControl() {
this.birth = String.format("%d/%d/%d",dp.getYear(),dp.getMonth()+1,dp.getDayOfMonth());
}
}
|
|
MainActivity ( No.1 ) |
|
日時: 2015/10/19 15:07
名前: lightbox
|
日時: 2015/10/19 15:07 名前: lightbox
拡張子:
package sample.lightbox.androidbind1017;
import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.Spinner;
import android.widget.TextView;
import com.google.gson.Gson;
import sample.lightbox.androidbind1017.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
// *************************************************
// 変数定義
// *************************************************
// WebView のインスタンス
private WebView wv = null;
// 表示されているページの URL
private String startPage = null;
// 初期表示ページ
private String initPage = "http://winofsql.jp/002.php";
private String[] list_data = {"営業部第一", "営業部第二", "営業部第三"};
private String[] list_value = {"0001", "0002", "0003"};
private Gson gson = null;
private Syain syain = null;
private Handler handler = null;
// *************************************************
// 画面定義から自動作成されるクラス
// ※ 名称は、xml のファイル名から作成されています
// *************************************************
private ActivityMainBinding binding = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// *************************************************
// 初期画面表示
// *************************************************
binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main);
// 共有情報
Syain.context = MainActivity.this;
Syain.np = (NumberPicker) MainActivity.this.findViewById(R.id.numberPicker);
Syain.sp = (Spinner)MainActivity.this.findViewById(R.id.spinner);
Syain.dp = (DatePicker)MainActivity.this.findViewById(R.id.datePicker);
// 初回バインド
syain = new Syain();
syain.setupSeibetuControl();
syain.setupSyozokuControl(list_data);
syain.setupBirthControl(true, false);
binding.setUser(syain);
// ダミーフィールドによる、先頭スクロールと 他のコントロールからのフォーカスオフ
((TextView)MainActivity.this.findViewById(R.id.topText)).requestFocus();
// *************************************************
// Webページの JavaScript の呼び出し
// *************************************************
MainActivity.this.findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText et = (EditText) MainActivity.this.findViewById(R.id.editText);
String scode = ((EditText) MainActivity.this.findViewById(R.id.editText)).getText().toString();
String callString = String.format("javascript:getWebPageData(\"%s\")", scode);
wv.loadUrl(callString);
}
});
// *************************************************
// SET
// *************************************************
MainActivity.this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
syain.furi = "ヘンコウサレマシタ";
syain.setSeibetuControl("2");
// 全ての Syain の内容を反映
// ※ @Bindable を使う事のメリットが無いので( fromJson が setter を使わない )
binding.invalidateAll();
}
});
// *************************************************
// GET
// *************************************************
MainActivity.this.findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// バインドは片方向なので入力結果を Syain に反映させる
syain.scode = ((EditText)MainActivity.this.findViewById(R.id.editText)).getText().toString();
syain.getSeibetuControl();
syain.getSyozokuControl(list_value);
syain.getBirthControl(MainActivity.this.findViewById(R.id.datePicker));
String json = gson.toJson(syain);
// この内容をサーバに送る
Log.i("lightbox",json);
}
});
// *************************************************
// 主要インスタンス
// *************************************************
handler = new Handler();
gson = new Gson();
// *************************************************
// WebView の目的ページ表示
// *************************************************
wv = (WebView) MainActivity.this.findViewById(R.id.webView);
// 目的のページを表示する
wv.loadUrl(initPage);
// *************************************************
// WebView の準備 ( 開始 )
// *************************************************
// Webページとのインターフェイスを登録します
// Webページ上からは、androidObject.toAndroid で呼ぶ事ができます
// (toAndroid は、@JavascriptInterface で登録したメソッド)
wv.addJavascriptInterface(new JavaScriptAccess(new JavaScriptAccess.OnGetWebDataListener() {
@Override
public void onWebGetDataListener(String textData) {
try {
syain = gson.fromJson(textData, Syain.class);
// 別スレッドから UI スレッドへのアクセス
handler.post(new Runnable() {
@Override
public void run() {
// *************************************
// 画面表示
// *************************************
binding.setUser(syain);
if ( !syain.kj.equals("ERROR")) {
// 現在の内容でコントロールセット( fromJson 用なので、null 指定 )
syain.setSeibetuControl(null);
syain.setSyozokuControl(null, list_value);
syain.setBirthControl(null);
// fromJson によって、syain にデータはセットされるので、画面に反映させる
binding.invalidateAll();
// ダミーフィールドによる、先頭スクロールと 他のコントロールからのフォーカスオフ
((TextView)MainActivity.this.findViewById(R.id.topText)).requestFocus();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}), "androidObject");
// 必ず必要な JavaScript を有効にする設定
wv.getSettings().setJavaScriptEnabled(true);
// 必ず必要な設定
wv.setWebViewClient(new WebViewClient() {
// 必ず必要な設定 : 常に WebView 内でページを表示する為
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.i("lightbox", "shouldOverrideUrlLoading" + url);
return super.shouldOverrideUrlLoading(view, url);
}
// オプション : 表示されたページの URL を変数にセット
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.i("lightbox", "onPageStarted:" + url);
startPage = url;
}
// オプション : ページを表示し終わってから発生するイベント
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
// *************************************************
// WebView の準備 ( 終わり )
// *************************************************
}
@Override
protected void onStop() {
super.onStop();
wv.clearHistory();
wv.clearCache(true);
Log.i("lightbox", "onStop");
}
}
|
activity_main.xml ( 主画面 ) ( No.2 ) |
日時: 2015/10/19 15:13 名前: lightbox
|
ex_contents.xml ( include される画面 / バインドの継承 ) ( No.3 ) |
日時: 2015/10/19 15:11 名前: lightbox
|
PHP ( No.4 ) |
日時: 2015/10/19 15:21 名前: lightbox
dbdata2_json.php
拡張子:
<?php
header( "Content-Type: application/json; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );
header( "Access-Control-Allow-Origin: *" );
$server = 'サーバー';
$db_name = 'データベース';
$user = 'ユーザ';
$password = 'パスワード';
$json_type = JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT;
$db_data_type = MYSQLI_ASSOC;
// 接続
$connect = new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
die('Connect Error (' . $connect->connect_errno . ') '
. $connect->connect_error);
}
$connect->set_charset("utf8");
$_GET["scode"] = str_replace("'","''",$_GET["scode"]);
$query = <<< QUERY
select
社員コード as scode,
氏名 as kj,
フリガナ as furi,
所属 syozoku,
性別 seibetu,
給与 kyuyo,
手当 teate,
管理者 kanri,
生年月日 birth,
コード名称マスタ.名称 as sname
from 社員マスタ
left outer join コード名称マスタ
on 社員マスタ.所属 = コード名称マスタ.コード
where コード名称マスタ.区分 = 2
and 社員コード = '{$_GET["scode"]}'
QUERY;
// クエリ
$result = $connect->query($query);
if ( !$result ) {
die('クエリーに誤りがあります : ' . $connect->error );
}
$check = false;
while ($row = $result->fetch_array($db_data_type)) {
$check = true;
print json_encode($row,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
print "\n";
}
// 開放
$result->close();
// 接続解除
$connect->close();
if (!$check) {
print <<< ERROR
{
"scode": "{$_GET["scode"]}",
"kj": "ERROR",
"furi": null,
"syozoku": null,
"seibetu": null,
"kyuyo": null,
"teate": null,
"kanri": null,
"birth": null,
"sname": null
}
ERROR;
}
?>
002.php
|
|
|
|