ソース掲示板




すべてから検索

キーワード   条件 表示 現行ログ 過去ログ トピックス 名前 本文
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");

	}

}
このアーティクルの参照用URLをクリップボードにコピー メンテナンス
activity_main.xml ( 主画面 ) ( No.2 )
日時: 2015/10/19 15:13
名前: lightbox
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:bind="http://schemas.android.com/apk/res-auto"
        tools:context=".MainActivity">

    <data>
        <variable
            name="user"
            type="sample.lightbox.androidbind1017.Syain"/>
    </data>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollView">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            android:paddingBottom="@dimen/activity_vertical_margin">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="1dp"
                android:id="@+id/topText"
                android:focusable="true"
                android:focusableInTouchMode="true"/>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/action">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="SET"
                    android:id="@+id/button"
                    android:layout_alignParentEnd="true"
                    android:layout_weight="1"/>

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="GET"
                    android:layout_weight="1"
                    android:id="@+id/button3"/>

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="JS CALL"
                    android:id="@+id/button2"
                    android:layout_weight="1"/>
            </LinearLayout>

            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/dataBody">

                <EditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@{user.scode}"
                    android:inputType="number"
                    android:id="@+id/editText"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@{user.kj}"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:id="@+id/textView"
                    android:layout_margin="4dp"
                    android:focusable="true"
                    android:focusableInTouchMode="true"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@{user.furi}"
                    android:id="@+id/textView2"
                    android:layout_margin="4dp"/>

            </LinearLayout>

            <include
                layout="@layout/ex_contents"
                android:id="@+id/ex"
                bind:user="@{user}"/>

            <WebView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:id="@+id/webView"
                android:visibility="visible"/>

        </LinearLayout>
    </ScrollView>
</layout>
このアーティクルの参照用URLをクリップボードにコピー メンテナンス
ex_contents.xml ( include される画面 / バインドの継承 ) ( No.3 )
日時: 2015/10/19 15:11
名前: lightbox
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:bind="http://schemas.android.com/apk/res-auto"
        tools:context=".MainActivity">

    <data>
        <variable
            name="user"
            type="sample.lightbox.androidbind1017.Syain"/>
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.syozoku}"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:id="@+id/textView3"
            android:layout_margin="4dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.sname}"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:id="@+id/textView4"
            android:layout_margin="4dp"/>

        <NumberPicker
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/numberPicker"/>

        <Spinner
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/spinner"
            android:spinnerMode="dropdown"/>

        <DatePicker
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/datePicker"
            android:datePickerMode="spinner"/>

    </LinearLayout>
</layout>
このアーティクルの参照用URLをクリップボードにコピー メンテナンス
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
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
function getWebPageData(scode) {
	// ***************************************
	// Android WebView の中のこのページ
	// より、サーバへアクセスします
	// ***************************************
	$.get("dbdata2_json.php?scode="+scode,function( data ){
		if ( typeof androidObject !== 'undefined' ) {
			// サーバから受け取った application/json データ
			// を文字列に変換して Android に渡します
			androidObject.toAndroid(JSON.stringify(data));
		}
		else {
			// 通常のブラウザではこちらが実行されます
			console.log(JSON.stringify(data,null,"   "));
		}
	})
}
</script>
</head>
<body>
<pre>
<?php
// Android の呼び出しテスト
?>
<input type="button" value="logcat test" onclick="androidObject.logcat('OK')">

<?php
// サーバからのデータで Android の呼び出しテスト
?>
<input type="button" value="toAndroid test" onclick="getWebPageData('0001')">

</pre>
</body>
</html>
このアーティクルの参照用URLをクリップボードにコピー メンテナンス