1) Livedoor の お天気Webサービス API を読み込んで JSON 文字列を取得します 2) Google Gson を使用して、JSON 文字列を Java のオブジェクトの配列に変換します 3) オブジェクトの配列を ArrayAdapter で ListView に表示します 4) メニューから『追加』『修正』『削除』『クリア』『一覧参照』の処理をテストします 5) Click と LongClick のイベントを使って、次画面に画面遷移します 6) Click では、Preferences を使い、LongClick では putExtra でオブジェクトを引き渡します 7) 次画面では、引き渡した内容を表示して、url のデータで WEBブラウザを開きます 8) 閉じるボタンを使用すると、呼び出し元へデータ(時間文字列)を戻します 9) 呼び出し元の画面で、onActivityResult で受けた場合は AlertDialog で戻されたデータを表示します Tools クラス ▼ Preferences の場所 MainActivity
package app.lightbox.winofsql.jp.weather; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import jp.android.work.Tools; public class MainActivity extends Activity { private ArrayAdapter<PinpointLocation> arrayMyData = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 専用クラス用 arrayMyData = new ArrayAdapter<PinpointLocation>( MainActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1 ); // WEBアクセス( HttpGet ) Button button = (Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Tools.callHttpGet("http://weather.livedoor.com/forecast/webservice/json/v1?city=270000", "utf-8", new Tools.OnAsyncTaskListener() { @Override public void onAsyncTaskListener(String s) { Gson gson = new Gson(); Weather weatherData = gson.fromJson(s, Weather.class); // ListView のインスタンスを取得 ListView listview = (ListView) MainActivity.this.findViewById(R.id.listView); // Weather クラス内の配列部分をセット arrayMyData.clear(); arrayMyData.addAll(weatherData.pinpointLocations); listview.setAdapter(arrayMyData); // 整形した json 文字列を再作成 Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); String json = prettyGson.toJson(weatherData); // アプリに保存 Tools.putPreferences(MainActivity.this, "lightbox", "init_all", json); } }); } }); // クリック(タップ)した時のイベント作成 ListView listview = (ListView) MainActivity.this.findViewById(R.id.listView); listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // クリックされたビューの内部データ Object data = (Object) parent.getItemAtPosition(position); PinpointLocation myData = (PinpointLocation) data; Log.i("lightbox", "name:" + myData.name +", url:" + myData.link); // アプリに保存 Tools.putPreferences(MainActivity.this, "lightbox", "url", myData.link); Tools.putPreferences(MainActivity.this, "lightbox", "name", myData.name); // 次画面の呼び出し Tools.callActivity(MainActivity.this, NextPage.class,NextPage.NEXT_PAGE); } }); // 長押し listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { PinpointLocation data = (PinpointLocation) parent.getItemAtPosition(position); Intent intent = new Intent(MainActivity.this,NextPage.class); // Serializable インターフェイスを持つオブジェクトのセット intent.putExtra("LongClick",data); startActivityForResult(intent, NextPage.NEXT_PAGE); // 単純クリックイベントを処理しない return true; } }); } // JSON 内の配列フォーマット public class Weather { PinpointLocation[] pinpointLocations; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if ( requestCode == NextPage.NEXT_PAGE ) { if ( resultCode == RESULT_OK) { String result = data.getStringExtra("時間"); Tools.messageBox(MainActivity.this, result, null); } } super.onActivityResult(requestCode, resultCode, data); } // メニューの処理 @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); // リストビューに追加 if (id == R.id.lv_action1) { // データを取得して 1 件以上ある場合 if ( arrayMyData.getCount() != 0 ) { // 新しくデータを追加 PinpointLocation data = new PinpointLocation(); // 久留米市 data.name = "\u4e45\u7559\u7c73\u5e02"; data.link = "http://weather.livedoor.com/area/forecast/4020300"; // 4番目に追加 arrayMyData.insert(data,3); return true; } } // 一覧を LogCat に表示 if (id == R.id.lv_action2) { if ( arrayMyData.getCount() != 0 ) { // ArrayAdapter からひとつづつ取り出す PinpointLocation data = null; int count = arrayMyData.getCount(); for (int i = 0; i < count; i++) { data = arrayMyData.getItem(i); Log.i("lightbox", data.name + ":" + data.link); } return true; } } // 全てクリア if (id == R.id.lv_action3) { if ( arrayMyData.getCount() != 0 ) { arrayMyData.clear(); return true; } } // 4番目を削除 if (id == R.id.lv_action4) { if ( arrayMyData.getCount() != 0 ) { // 4番目の内容を取り出す PinpointLocation data = null; data = arrayMyData.getItem(3); arrayMyData.remove(data); return true; } } // 4番目を変更 if (id == R.id.lv_action5) { if ( arrayMyData.getCount() != 0 ) { // 4番目の内容を取り出す PinpointLocation data = null; data = arrayMyData.getItem(3); // 時間データをタイトルにする String time = Tools.getDateString("HH'時'mm'分'ss'秒'"); // データを再設定 data.name = time; // 変更を通知 arrayMyData.notifyDataSetChanged(); return true; } } Toast.makeText(MainActivity.this,"データがありません",Toast.LENGTH_LONG).show(); return super.onOptionsItemSelected(item); } // メニュー作成 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } }
NextPage
package app.lightbox.winofsql.jp.weather; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import jp.android.work.Tools; /** * Created by lightbox on 2015/06/15. */ public class NextPage extends Activity { public static final int NEXT_PAGE = 100; private PinpointLocation data = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_nextpage); TextView textView = (TextView) NextPage.this.findViewById(R.id.textView); // 前画面から渡されたオブジェクトの取得 Intent intent = NextPage.this.getIntent(); data = (PinpointLocation)intent.getSerializableExtra("LongClick"); // ただのクリック if ( data == null ) { // data が null なので作成 data = new PinpointLocation(); data.link = Tools.getPreferences(NextPage.this, "lightbox", "url"); data.name = Tools.getPreferences(NextPage.this, "lightbox", "name"); textView.setText(data.name); } // 長押し else { textView.setText(data.link); } Button webButton = (Button) NextPage.this.findViewById(R.id.button2); webButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Tools.callBrowser(NextPage.this,data.link); } }); // 終了ボタン Button closeButton = (Button) NextPage.this.findViewById(R.id.button3); closeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = NextPage.this.getIntent(); intent.putExtra("時間",Tools.getDateString("HH'時'mm'分'ss'秒'")); setResult(RESULT_OK,intent); finish(); } }); } }
PinpointLocation
package app.lightbox.winofsql.jp.weather; import java.io.Serializable; /** * Created by lightbox on 2015/06/15. */ // 一行ぶんのデータフォーマット public class PinpointLocation implements Serializable { String link; String name; @Override public String toString() { return name; } }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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" tools:context=".MainActivity"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="HttpGet" android:id="@+id/button" android:layout_alignParentTop="true" android:layout_alignParentStart="true"/> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_below="@+id/button" android:layout_alignParentStart="true"/> </RelativeLayout>
layout_nextpage.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/textView" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:padding="10dp"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Webブラウザを開く" android:id="@+id/button2" android:layout_below="@+id/textView" android:layout_alignParentStart="true" android:textSize="20dp"/> <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="閉じる" android:id="@+id/button3" android:layout_below="@+id/button2" android:layout_centerHorizontal="true" android:textSize="60dp"/> </RelativeLayout>
メニュー定義
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/lv_action1" android:title="追加" android:orderInCategory="100" android:showAsAction="never"/> <item android:id="@+id/lv_action2" android:title="一覧を LogCat に表示" android:orderInCategory="100" android:showAsAction="never"/> <item android:id="@+id/lv_action3" android:title="クリア" android:orderInCategory="100" android:showAsAction="never"/> <item android:id="@+id/lv_action4" android:title="削除" android:orderInCategory="100" android:showAsAction="never"/> <item android:id="@+id/lv_action5" android:title="変更" android:orderInCategory="100" android:showAsAction="never"/> </menu>
関連するリンク集 Java 関連リンク ( 主に Android )