您的位置:首页 > 移动开发 > Android开发

com.example.android.hcgallery 分析

2016-01-11 15:23 423 查看
com.example.android.hcgallery 是一个简单的android SDK程序,完成功能是把图像分类,按类别进行分类显示。1:在UI上使用tab来组织各个类别;2:按listView
选择图像3:可共享图片。所以此程序主要有3个功能。另外图片拖动的功能不分析。一个比较小的功能是图片的全屏显示与否。
1。 数据源的相关类
没太多特别的地方
mCategories = new DirectoryCategory[] {
new DirectoryCategory("Balloons", new DirectoryEntry[] {
new DirectoryEntry("Red Balloon", R.drawable.red_balloon),
new DirectoryEntry("Green Balloon", R.drawable.green_balloon),
new DirectoryEntry("Blue Balloon", R.drawable.blue_balloon)}),
new DirectoryCategory("Bikes", new DirectoryEntry[] {
new DirectoryEntry("Old school huffy", R.drawable.blue_bike),
new DirectoryEntry("New Bikes", R.drawable.rainbow_bike),
new DirectoryEntry("Chrome Fast", R.drawable.chrome_wheel)}),
new DirectoryCategory("Androids", new DirectoryEntry[] {
new DirectoryEntry("Steampunk Android", R.drawable.punk_droid),
new DirectoryEntry("Stargazing Android", R.drawable.stargazer_droid),
new DirectoryEntry("Big Android", R.drawable.big_droid) }),
new DirectoryCategory("Pastries", new DirectoryEntry[] {
new DirectoryEntry("Cupcake", R.drawable.cupcake),
new DirectoryEntry("Donut", R.drawable.donut),
new DirectoryEntry("Eclair", R.drawable.eclair),
new DirectoryEntry("Froyo", R.drawable.froyo), }), };
比较有意思,其实想一想没太多的新东西

2。图片显示
图片显示使用了一个activity和fragment,activity没有太多的东西,因为显示图片的来源先传到activity,所以要把他们继续传递下去。
Activity::onCreate --> Activity::setContentView --> Activity::onCreateView --> Activity::addFragment -->
--》Fragment::onAttach()
--》Activity::onAttachFragment()--》Fragment:: onCreateView
Fragment::onActivityCreated();
根据上图,fragment已创建,直接在onCreate中
ContentFragment frag = (ContentFragment) getFragmentManager().findFragmentById(R.id.content_frag);
frag.updateContentAndRecycleBitmap(category, position);


但是在
contentFragment
public void onActivityCreated(Bundle savedInstanceState)
又根据savedInstance中的内容重新
frag.updateContentAndRecycleBitmap(category, position);
显然有一次是多余的。
在此函数中:
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
// Must call in order to get callback to onOptionsItemSelected()
setHasOptionsMenu(true);,
enable了菜单项,但其实只有up一个菜单项。 android.R.id.home,处理如下:
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // Reuse the existing instance
startActivity(intent);
Intent.FLAG_ACTIVITY_CLEAR_TOP 比较有意思


既然使用了savedInstanceState,就有保存的函数 public void
onSaveInstanceState (Bundle outState)

mContentView.setOnClickListener()在点击图像时进入或退出全屏模式,具体操作如下

Window window = getActivity().getWindow();
WindowManager.LayoutParams winParams = window.getAttributes();
View view = getView();
ActionBar actionBar = getActivity().getActionBar();
// Show status bar (remove fullscreen flag)
window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Show system bar
view.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
// Show action bar
actionBar.show();

contextual Action Bar mode
CAB可以支持一次选择多个list item,对这些item进行同一个操作。CAB的实现如下:
mCurrentActionMode = getActivity().startActionMode(
mContentSelectionActionModeCallback);
private ActionMode.Callback mContentSelectionActionModeCallback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
actionMode.setTitle(R.string.photo_selection_cab_title);

MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.photo_context_menu, menu);
return true;
}

public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}

public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.menu_share:
shareCurrentPhoto();
actionMode.finish();
return true;
}
return false;
}

public void onDestroyActionMode(ActionMode actionMode) {
mContentView.setSelected(false);
mCurrentActionMode = null;
}
};
shareCurrentPhoto中
先把图片存储到一个特定的目录,然后
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, "Share photo"));
这个目录有个特别的文件.nomedia 防止media软件扫描。

因为存储和共享需要时间,所以使用了一个ASyncTask来处理。

3。 目录显示,使用fragment显示
目录显示主要使用了actionbar的tab功能。

启用tab功能:
ActionBar bar = getActivity().getActionBar();
bar.setDisplayHomeAsUpEnabled(false);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
增加tab
for (int i = 0; i < Directory.getCategoryCount(); i++) {
bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName())
.setTabListener(this));
}
选择tab
bar.selectTab(bar.getTabAt(mCategory));
tab中list内容的填充,使用了listAdapter
class TitlesFragment extends ListFragment implements ActionBar.TabListener
setListAdapter(new ArrayAdapter<String>(getActivity(),
R.layout.title_list_item, items));
侦听tab点击的动作
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
TitlesFragment titleFrag = (TitlesFragment) getFragmentManager()
.findFragmentById(R.id.titles_frag);
titleFrag.populateTitles(tab.getPosition());

if (mDualFragments) {
titleFrag.selectPosition(0);
}
}
侦听 list item点击的动作
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity via OnItemSelectedListener callback
mListener.onItemSelected(mCategory, position);
mCurPosition = position;
}
侦听 layout改变的事件
ViewTreeObserver observer = getListView().getViewTreeObserver();
observer.addOnGlobalLayoutListener(layoutListener);
ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int barHeight = getActivity().getActionBar().getHeight();
ListView listView = getListView();
FrameLayout.LayoutParams params = (LayoutParams) listView.getLayoutParams();
// The list view top-margin should always match the action bar height
if (params.topMargin != barHeight) {
params.topMargin = barHeight;  //如果此行去掉,那么listView和Action View就混在一起了。
listView.setLayoutParams(params);
}
// The action bar doesn't update its height when hidden, so make top-margin zero
if (!getActivity().getActionBar().isShowing()) {
params.topMargin = 0;
listView.setLayoutParams(params);
}
}
};

4。显示对话框。使用dialogFragment
void showDialog(String text) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction.  We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = MyDialogFragment.newInstance(text);
// Show the dialog.
newFragment.show(ft, "dialog");
}
public static class MyDialogFragment extends DialogFragment {

public static MyDialogFragment newInstance(String title) {
MyDialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("text", title);
frag.setArguments(args);
return frag;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String text = getArguments().getString("text");

return new AlertDialog.Builder(getActivity())
.setTitle("A Dialog of Awesome")
.setMessage(text)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.create();
}
}
在接受到intent时显示对话框
protected void onNewIntent(Intent intent) {
if (ACTION_DIALOG.equals(intent.getAction())) {
showDialog(intent.getStringExtra(Intent.EXTRA_TEXT));
}
}
定义Action
<intent-filter>
<action android:name="com.example.android.hcgallery.action.DIALOG" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
构建intent
PendingIntent getDialogPendingIntent(String dialogText) {
return PendingIntent.getActivity(
this,
dialogText.hashCode(), // Otherwise previous PendingIntents with the same
// requestCode may be overwritten.
new Intent(ACTION_DIALOG)
.putExtra(Intent.EXTRA_TEXT, dialogText)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
0);
}


5。显示notification

void showNotification(boolean custom) {
final Resources res = getResources();
final NotificationManager notificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE);

Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notify_example)
.setAutoCancel(true)
.setTicker(getString(R.string.notification_text))
.setContentIntent(getDialogPendingIntent("Tapped the notification entry."));

if (custom) {
// Sets a custom content view for the notification, including an image button.
RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
layout.setOnClickPendingIntent(R.id.notification_button,
getDialogPendingIntent("Tapped the 'dialog' button in the notification."));
此为当pressure imagebutton时显示不同与press其他部位的的对话框。
builder.setContent(layout);

// Notifications in Android 3.0 now have a standard mechanism for displaying large
// bitmaps such as contact avatars. Here, we load an example image and resize it to the
// appropriate size for large bitmaps in notifications.
Bitmap largeIconTemp = BitmapFactory.decodeResource(res,
R.drawable.notification_default_largeicon);
Bitmap largeIcon = Bitmap.createScaledBitmap(
largeIconTemp,
res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height),
false);
largeIconTemp.recycle();

builder.setLargeIcon(largeIcon);

} else {
builder
.setNumber(7) // An example number.
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notification_text));
}

notificationManager.notify(NOTIFICATION_DEFAULT, builder.getNotification());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: