-
-
Save karupanerura/cd5da36f7f4378b08fcb to your computer and use it in GitHub Desktop.
マッチョなActivityサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.yanzm.profileapplication; | |
import android.animation.Animator; | |
import android.animation.AnimatorListenerAdapter; | |
import android.animation.AnimatorSet; | |
import android.animation.ObjectAnimator; | |
import android.app.Activity; | |
import android.app.AlertDialog; | |
import android.content.DialogInterface; | |
import android.content.Intent; | |
import android.graphics.Bitmap; | |
import android.net.Uri; | |
import android.os.AsyncTask; | |
import android.os.Bundle; | |
import android.provider.MediaStore; | |
import android.support.annotation.IntDef; | |
import android.support.annotation.NonNull; | |
import android.text.TextUtils; | |
import android.util.Log; | |
import android.view.LayoutInflater; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.widget.Button; | |
import android.widget.EditText; | |
import android.widget.ImageView; | |
import android.widget.LinearLayout; | |
import android.widget.RadioGroup; | |
import android.widget.Spinner; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
import com.squareup.picasso.Picasso; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Random; | |
public class MainActivity extends Activity { | |
private static final int REQUEST_CODE_PICK_IMAGE = 1; | |
private ImageView thumbnailView; | |
private EditText nameEditText; | |
private EditText bioEditText; | |
private Spinner experienceSpinner; | |
private RadioGroup eventGroup; | |
private LinearLayout dessertContainer; | |
private Button sendButton; | |
private View progressView; | |
private View profileContainer; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
assert getActionBar() != null; | |
getActionBar().setDisplayHomeAsUpEnabled(true); | |
// ビューの設定 | |
progressView = findViewById(R.id.progress); | |
profileContainer = findViewById(R.id.profile_container); | |
thumbnailView = (ImageView) findViewById(R.id.thumbnail); | |
thumbnailView.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); | |
intent.addCategory(Intent.CATEGORY_OPENABLE); | |
intent.setType("image/*"); | |
startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE); | |
} | |
}); | |
nameEditText = (EditText) findViewById(R.id.name); | |
experienceSpinner = (Spinner) findViewById(R.id.experience); | |
bioEditText = (EditText) findViewById(R.id.bio); | |
eventGroup = (RadioGroup) findViewById(R.id.event); | |
dessertContainer = (LinearLayout) findViewById(R.id.dessert_container); | |
findViewById(R.id.add_dessert_button).setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
final String[] desserts = getResources().getStringArray(R.array.desserts); | |
new AlertDialog.Builder(MainActivity.this) | |
.setItems(desserts, new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialog, int which) { | |
String item = desserts[which]; | |
final int childCount = dessertContainer.getChildCount(); | |
for (int i = 0; i < childCount; i++) { | |
final View child = dessertContainer.getChildAt(i); | |
String dessert = ((TextView) child).getText().toString(); | |
if (dessert.equals(item)) { | |
Toast.makeText(MainActivity.this, "すでに選択されています", Toast.LENGTH_SHORT).show(); | |
return; | |
} | |
} | |
final TextView tv = (TextView) getLayoutInflater() | |
.inflate(R.layout.dessert_item, dessertContainer, false); | |
tv.setText(desserts[which]); | |
tv.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
new AlertDialog.Builder(MainActivity.this) | |
.setMessage("削除しますか?") | |
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialog, int which) { | |
dessertContainer.removeView(tv); | |
} | |
}) | |
.setNegativeButton(android.R.string.cancel, null) | |
.show(); | |
} | |
}); | |
dessertContainer.addView(tv); | |
} | |
}) | |
.show(); | |
} | |
}); | |
sendButton = (Button) findViewById(R.id.send_button); | |
sendButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
// バリデーション | |
if (validate()) { | |
send(); | |
} | |
} | |
}); | |
// 画面回転対応 | |
if (savedInstanceState != null) { | |
progressView.setVisibility(View.GONE); | |
return; | |
} | |
// プログレスを表示 | |
progressView.setVisibility(View.VISIBLE); | |
// (同期)編集フォームを非表示or無効化 | |
profileContainer.setVisibility(View.GONE); | |
// 1. サーバーからプロフィールデータを取得 | |
AsyncTask<Void, Void, ProfileData> task = new AsyncTask<Void, Void, ProfileData>() { | |
@Override | |
protected ProfileData doInBackground(Void... params) { | |
return getProfileData(); | |
} | |
@Override | |
protected void onPostExecute(ProfileData profileData) { | |
// 2. プロフィールデータを表示 | |
if (!TextUtils.isEmpty(profileData.imageUrl)) { | |
Picasso.with(MainActivity.this).load(profileData.imageUrl).into(thumbnailView); | |
} | |
nameEditText.setText(profileData.name); | |
bioEditText.setText(profileData.bio); | |
experienceSpinner.setSelection(profileData.experience); | |
int id = -1; | |
switch (profileData.eventStatus) { | |
case 0: | |
id = R.id.attend; | |
break; | |
case 1: | |
id = R.id.not_attend; | |
break; | |
case 2: | |
id = R.id.attend; | |
break; | |
} | |
eventGroup.check(id); | |
for (String dessert : profileData.favoriteDessert) { | |
LayoutInflater inflater = getLayoutInflater(); | |
final TextView tv = (TextView) inflater.inflate(R.layout.dessert_item, dessertContainer, false); | |
tv.setText(dessert); | |
tv.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
new AlertDialog.Builder(MainActivity.this) | |
.setMessage("削除しますか?") | |
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialog, int which) { | |
dessertContainer.removeView(tv); | |
} | |
}) | |
.setNegativeButton(android.R.string.cancel, null) | |
.show(); | |
} | |
}); | |
dessertContainer.addView(tv); | |
} | |
// 編集フォームを表示or有効化 | |
profileContainer.setVisibility(View.VISIBLE); | |
final AnimatorSet animatorSet = new AnimatorSet(); | |
animatorSet.playTogether( | |
ObjectAnimator.ofFloat(profileContainer, "alpha", 0f, 1f), | |
ObjectAnimator.ofFloat(progressView, "alpha", 1f, 0f) | |
); | |
animatorSet.addListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
super.onAnimationEnd(animation); | |
animatorSet.removeListener(this); | |
// プログレスを非表示 | |
progressView.setVisibility(View.GONE); | |
} | |
}); | |
animatorSet.start(); | |
} | |
}.execute(); | |
} | |
private static final String KEY_IMAGE_URI = "image_uri"; | |
private static final String KEY_DESSERT_LIST = "dessert_list"; | |
@Override | |
protected void onSaveInstanceState(Bundle outState) { | |
super.onSaveInstanceState(outState); | |
Uri uri = (Uri) thumbnailView.getTag(); | |
if (uri != null) { | |
outState.putString(KEY_IMAGE_URI, uri.toString()); | |
} | |
ArrayList<String> dessertList = new ArrayList<>(); | |
final int childCount = dessertContainer.getChildCount(); | |
for (int i = 0; i < childCount; i++) { | |
final View child = dessertContainer.getChildAt(i); | |
if (child instanceof TextView) { | |
dessertList.add(((TextView) child).getText().toString()); | |
} | |
} | |
outState.putStringArrayList(KEY_DESSERT_LIST, dessertList); | |
} | |
@Override | |
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { | |
super.onRestoreInstanceState(savedInstanceState); | |
final String uriString = savedInstanceState.getString(KEY_IMAGE_URI); | |
if (!TextUtils.isEmpty(uriString)) { | |
Uri uri = Uri.parse(uriString); | |
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); | |
try { | |
Bitmap bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); | |
thumbnailView.setImageBitmap(bmp); | |
thumbnailView.setTag(uri); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
ArrayList<String> dessertList = savedInstanceState.getStringArrayList(KEY_DESSERT_LIST); | |
for (String dessert : dessertList) { | |
LayoutInflater inflater = getLayoutInflater(); | |
final TextView tv = (TextView) inflater.inflate(R.layout.dessert_item, dessertContainer, false); | |
tv.setText(dessert); | |
tv.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
new AlertDialog.Builder(MainActivity.this) | |
.setMessage("削除しますか?") | |
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialog, int which) { | |
dessertContainer.removeView(tv); | |
} | |
}) | |
.setNegativeButton(android.R.string.cancel, null) | |
.show(); | |
} | |
}); | |
dessertContainer.addView(tv); | |
} | |
} | |
private boolean validate() { | |
// バリデーション失敗: エラーメッセージ表示 | |
final String name = nameEditText.getText().toString(); | |
if (TextUtils.isEmpty(name)) { | |
Toast.makeText(MainActivity.this, "名前が入力されていません", Toast.LENGTH_SHORT).show(); | |
return false; | |
} | |
final int id = eventGroup.getCheckedRadioButtonId(); | |
if (id != R.id.attend && id != R.id.not_attend && id != R.id.unknown) { | |
Toast.makeText(MainActivity.this, "DroidKaigiが選択されていません", Toast.LENGTH_SHORT).show(); | |
return false; | |
} | |
return true; | |
} | |
private void send() { | |
final Uri imageUri = (Uri) thumbnailView.getTag(); | |
final ProfileData profileData = new ProfileData(); | |
profileData.name = nameEditText.getText().toString(); | |
profileData.bio = bioEditText.getText().toString(); | |
final int position = experienceSpinner.getSelectedItemPosition(); | |
switch (position) { | |
case 0: | |
profileData.experience = ProfileData.EXPERIENCE_U1; | |
break; | |
case 1: | |
profileData.experience = ProfileData.EXPERIENCE_U2; | |
break; | |
case 2: | |
profileData.experience = ProfileData.EXPERIENCE_U3; | |
break; | |
case 3: | |
profileData.experience = ProfileData.EXPERIENCE_U4; | |
break; | |
case 4: | |
profileData.experience = ProfileData.EXPERIENCE_U5; | |
break; | |
case 5: | |
profileData.experience = ProfileData.EXPERIENCE_O5; | |
break; | |
default: | |
return; | |
} | |
final int id = eventGroup.getCheckedRadioButtonId(); | |
switch (id) { | |
case R.id.attend: | |
profileData.eventStatus = ProfileData.EVENT_STATUS_ATTEND; | |
break; | |
case R.id.not_attend: | |
profileData.eventStatus = ProfileData.EVENT_STATUS_NOT_ATTEND; | |
break; | |
case R.id.unknown: | |
profileData.eventStatus = ProfileData.EVENT_STATUS_UNKNOWN; | |
break; | |
default: | |
return; | |
} | |
List<String> favoriteDessert = new ArrayList<>(); | |
final int childCount = dessertContainer.getChildCount(); | |
for (int i = 0; i < childCount; i++) { | |
final View child = dessertContainer.getChildAt(i); | |
if (child instanceof TextView) { | |
favoriteDessert.add(((TextView) child).getText().toString()); | |
} | |
} | |
profileData.favoriteDessert = favoriteDessert; | |
// 送信ボタン無効化 | |
sendButton.setEnabled(false); | |
// プログレスを表示 | |
progressView.setVisibility(View.VISIBLE); | |
progressView.animate().alpha(1f); | |
// 5. データの更新をサーバーに送信 | |
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() { | |
@Override | |
protected Boolean doInBackground(Void... params) { | |
if (imageUri != null) { | |
String imageUrl = sendImage(imageUri); | |
if (TextUtils.isEmpty(imageUrl)) { | |
return false; | |
} | |
profileData.imageUrl = imageUrl; | |
} | |
return sendProfileData(profileData); | |
} | |
@Override | |
protected void onPostExecute(Boolean result) { | |
if (isFinishing()) { | |
return; | |
} | |
if (result) { | |
Toast.makeText(MainActivity.this, "更新しました", Toast.LENGTH_SHORT).show(); | |
finish(); | |
} else { | |
Toast.makeText(MainActivity.this, "更新できませんでした", Toast.LENGTH_SHORT).show(); | |
// 送信ボタン有効化 | |
sendButton.setEnabled(true); | |
final ObjectAnimator animator = ObjectAnimator.ofFloat(progressView, "alpha", 1f, 0f); | |
animator.addListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
super.onAnimationEnd(animation); | |
animator.removeListener(this); | |
// プログレスを非表示 | |
progressView.setVisibility(View.GONE); | |
} | |
}); | |
animator.start(); | |
} | |
} | |
}.execute(); | |
} | |
private String sendImage(Uri imageUri) { | |
// ネットワーク通信をダミーするためにスリープ | |
try { | |
Thread.sleep(3000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return "https://pbs.twimg.com/profile_images/542953617108398081/Gs_eKy2k.jpeg"; | |
} | |
Random random = new Random(); | |
private ProfileData getProfileData() { | |
// ネットワーク通信をダミーするためにスリープ | |
try { | |
Thread.sleep(3000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
ProfileData profileData = new ProfileData(); | |
profileData.name = random.nextBoolean() ? "Droid" : ""; | |
if (!TextUtils.isEmpty(profileData.name)) { | |
profileData.imageUrl = "https://dl.dropboxusercontent.com/u/7053182/ic_yanzm.jpeg"; | |
profileData.bio = random.nextBoolean() ? "世界をまたにかけるAndroid開発者" : ""; | |
int experience = random.nextInt(6); // 0 〜 5; | |
switch (experience) { | |
case 0: | |
profileData.experience = ProfileData.EXPERIENCE_U1; | |
break; | |
case 1: | |
profileData.experience = ProfileData.EXPERIENCE_U2; | |
break; | |
case 2: | |
profileData.experience = ProfileData.EXPERIENCE_U3; | |
break; | |
case 3: | |
profileData.experience = ProfileData.EXPERIENCE_U4; | |
break; | |
case 4: | |
profileData.experience = ProfileData.EXPERIENCE_U5; | |
break; | |
case 5: | |
profileData.experience = ProfileData.EXPERIENCE_O5; | |
break; | |
} | |
int eventStatus = random.nextInt(3); // 0 〜 2; | |
switch (eventStatus) { | |
case 0: | |
profileData.eventStatus = ProfileData.EVENT_STATUS_ATTEND; | |
break; | |
case 1: | |
profileData.eventStatus = ProfileData.EVENT_STATUS_NOT_ATTEND; | |
break; | |
case 2: | |
profileData.eventStatus = ProfileData.EVENT_STATUS_UNKNOWN; | |
break; | |
} | |
final String[] desserts = getResources().getStringArray(R.array.desserts); | |
int start = random.nextInt(desserts.length); | |
int size = random.nextInt(desserts.length); | |
List<String> favoriteDessert = new ArrayList<>(); | |
for (int i = start; i < start + size && i < desserts.length; i++) { | |
favoriteDessert.add(desserts[i]); | |
} | |
profileData.favoriteDessert = favoriteDessert; | |
} | |
return profileData; | |
} | |
private boolean sendProfileData(ProfileData profileData) { | |
// ネットワーク通信をダミーするためにスリープ | |
try { | |
Thread.sleep(3000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return random.nextBoolean(); | |
} | |
public static class ProfileData { | |
@Retention(RetentionPolicy.SOURCE) | |
@IntDef({EVENT_STATUS_ATTEND, EVENT_STATUS_NOT_ATTEND, EVENT_STATUS_UNKNOWN}) | |
public @interface EventStatus { | |
} | |
public static final int EVENT_STATUS_ATTEND = 0; | |
public static final int EVENT_STATUS_NOT_ATTEND = 1; | |
public static final int EVENT_STATUS_UNKNOWN = 2; | |
@Retention(RetentionPolicy.SOURCE) | |
@IntDef({EXPERIENCE_U1, EXPERIENCE_U2, EXPERIENCE_U3, EXPERIENCE_U4, EXPERIENCE_U5, EXPERIENCE_O5}) | |
public @interface Experience { | |
} | |
public static final int EXPERIENCE_U1 = 0; | |
public static final int EXPERIENCE_U2 = 1; | |
public static final int EXPERIENCE_U3 = 2; | |
public static final int EXPERIENCE_U4 = 3; | |
public static final int EXPERIENCE_U5 = 4; | |
public static final int EXPERIENCE_O5 = 5; | |
String imageUrl; | |
String name; | |
String bio; | |
@Experience | |
int experience = 0; | |
@EventStatus | |
int eventStatus = -1; | |
List<String> favoriteDessert = new ArrayList<>(); | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
if (item.getItemId() == android.R.id.home) { | |
finish(); | |
return true; | |
} | |
return super.onOptionsItemSelected(item); | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
if (requestCode == REQUEST_CODE_PICK_IMAGE) { | |
if (resultCode != RESULT_OK) { | |
return; | |
} | |
final Uri uri = data.getData(); | |
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); | |
try { | |
Bitmap bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); | |
thumbnailView.setImageBitmap(bmp); | |
thumbnailView.setTag(uri); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
return; | |
} | |
super.onActivityResult(requestCode, resultCode, data); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment