Solution:
自己斟酌是否把防毒軟體暫停關掉,之後重新更新,便可以順利進行。
搜尋此網誌
2015年12月6日 星期日
2015年11月29日 星期日
2015年11月25日 星期三
2015年11月21日 星期六
2015年11月12日 星期四
【Android】SparseBooleanArray 應用
ref:
checkboxes using SparseBooleanArray-StackOverflow
SparseArray淺析
checkboxes using SparseBooleanArray-StackOverflow
SparseArray淺析
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
.... | |
SparseBooleanArray checkedPositions = ((AlertDialog) dialog).getListView().getCheckedItemPositions(); | |
String print = ""; | |
int[] array = asIntArray(checkedPositions); | |
for (int i = 0; i < array.length; i++) { | |
print = print + " " + array[i]; | |
} | |
.... | |
private static int[] asIntArray(SparseBooleanArray checkedItems) { | |
int checked = 0; | |
// compute number of items | |
for (int i = 0; i < checkedItems.size(); i++) { | |
int key = checkedItems.keyAt(i); | |
if (checkedItems.get(key)) { | |
++checked; | |
} | |
} | |
int[] array = new int[checked]; | |
//add indexes that are checked | |
for (int i = 0, j = 0; i < checkedItems.size(); i++) { | |
int key = checkedItems.keyAt(i); | |
if (checkedItems.get(key)) { | |
array[j++] = key; | |
} | |
} | |
Arrays.sort(array); | |
return array; | |
} |
2015年10月10日 星期六
【Android】實作RecyclerView + ToolBar + SearchView
ref:
http://developer.android.com/intl/zh-tw/training/material/lists-cards.html
http://stackoverflow.com/a/30429439
http://blog.30sparks.com/material-design-4-recyclerview/ (2016/01/01 新增)
http://developer.android.com/intl/zh-tw/training/material/lists-cards.html
http://stackoverflow.com/a/30429439
http://blog.30sparks.com/material-design-4-recyclerview/ (2016/01/01 新增)
Gradle:
compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:design:23.3.0' compile 'com.android.support:recyclerview-v7:23.1.0'
res/menu:
在ToolBar新增一個搜尋圖案的按鈕<item android:id="@+id/search" android:icon="@drawable/ic_search_black_24dp" android:title="Search" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="collapseActionView|ifRoom" />
res/layout:
RecyclerView<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</FrameLayout>
MainLayout:
content_main指的就是recyclerview
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.example.searchview.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay"/> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main"/> <!--<include layout="@layout/FAB/">--> </android.support.design.widget.CoordinatorLayout>
MainActivity:
onCreate//Toolbar Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); //預設資料 availableLocales = new ArrayList<>(); for (Locale l : Locale.getAvailableLocales()) { availableLocales.add(l.getDisplayName()); } //RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); mRecyclerView.setHasFixedSize(true); //線性布局 mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new LanguageAdapter(availableLocales); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setItemAnimator(new DefaultItemAnimator());
RecyclerView布局Manager有三種:
- 線性佈局:mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
- 格狀佈局:mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));
- 瀑布佈局(縱向或橫向):mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL)); //HORIZONTAL
- 設定view為預設動畫:mRecyclerView.setItemAnimator(new DefaultItemAnimator());
- 在adapter使用以下函數,再搭配handler postdelay,可有動畫產生。
notifyItemChanged(int) notifyItemInserted(int) notifyItemRemoved(int) notifyItemMoved(int, int) notifyItemRangeChanged(int, int) notifyItemRangeInserted(int, int) notifyItemRangeRemoved(int, int)
- int為position位址
Adapter & ViewHolder:
private class LanguageAdapter extends RecyclerView.Adapter<ViewHolder> { private List<String> mLocales; private LanguageAdapter(List<String> mLocales) { this.mLocales = mLocales; notifyDataSetChanged(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { TextView tv = (TextView) LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new ViewHolder(tv); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.mTextView.setText(mLocales.get(position)); } @Override public int getItemCount() { return mLocales.size(); } } private static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(TextView v) { super(v); mTextView = v; } }
Menu
onCreateOptionsMenu設定當Search按鈕觸發後的動作,在這裡設定當,搜尋列輸入文字時,立刻判斷預設資料是否包含收尋文字,並透過adapter作即時更新→notifyDatachanged()。
getMenuInflater().inflate(R.menu.menu_main, menu); final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { mRecyclerView.setAdapter(new LanguageAdapter(OnFilter(availableLocales, newText))); return true; } }); return true;
判斷輸入文字method,回傳List形態結果
//判斷輸入文字 private List<String> OnFilter(List<String> filterLocales, String text) { String search = text.toLowerCase(); final List<String> filtered = new ArrayList<>(); for (String info : filterLocales) { final String localeName = info.toLowerCase(); if (localeName.contains(search)) { filtered.add(localeName); } } return filtered; }
結果示意圖
2015年10月7日 星期三
【Design Pattern】
定義了演算法家族,個別封裝起來,讓他們之間可以互相替換,此模式讓演算法的變動,不會影響到使用演算法的程式。
設計守則
- 找出程式中可能需要更動之處,把它們獨立出來,不要和那些不需要更動的程式碼混在一起。
換句話說:
把會變動的部份取出並封裝起來,以便以後可以輕易地擴充此部分,而不影響不需要更動的其他部分。 - 寫程式是針對介面而寫,而不是針對實踐方式而寫。
- 多用合成,少用繼承。
觀察者模式
定義了物件之間的一對多關係,如此一來,當一個物件改變狀態,其他相依者都會收到通知並自動更新。
- 設計時,盡量讓需要互動的元件之間關係鬆綁。
2015年9月23日 星期三
2015年9月22日 星期二
【Android】How to create a common class for alertDialog Box
ref:http://stackoverflow.com/a/8585364
Create a class like CustomDialog.class,
and inside of it create a static method like the one below,
public static void ExitAppDialog(final Activity activity)
{
AlertDialog.Builder alertbox = new AlertDialog.Builder(activity);
alertbox.setTitle("Warning");
alertbox.setMessage("Exit Application?");
alertbox.setPositiveButton("Yes", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
activity.finish();
}
});
alertbox.setNegativeButton("No", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
});
alertbox.show();
}
And in your activity's onBackPressed() call this method like this,
public void onBackPressed()
{
CustomDialog.ExitAppDialog(myActivity.this );
}
2015年9月20日 星期日
【Android】java.lang.IllegalStateException: Fragment not attached to Activity
ref:
http://stackoverflow.com/a/22544283
http://stackoverflow.com/a/22544283
Generally you get that error when you try to perform work after the Fragment is no longer attached to the Activity. In the callback that triggers the IllegalStateException add a check for isAdded:http://developer.android.com/reference/android/app/Fragment.html#isAdded()
if(!isAdded()) {
return;
}
http://stackoverflow.com/a/10941410
I've found the very simple answer:
isAdded()
:Returntrue
if the fragment is currently added to its activity.
@Override
protected void onPostExecute(Void result){
if(isAdded()){
getResources().getString(R.string.app_name);
}
}
To avoid
onPostExecute
from being called when the Fragment
is not attached to the Activity
is to cancel the AsyncTask
when pausing or stopping the Fragment
. Then isAdded()
would not be necessary anymore.【Android】移除FragmentManager裡的BackStack entry
ref:
Is this the right way to clean-up Fragment back stack when leaving a deeply nested stack?
http://shareandopen.tumblr.com/post/35328568659/android-clear-all-back-stack
為了好的使用者體驗,希望在程式運作到某一個情境時,清除所有的back stack entry,讓使用者不要在按下back按鍵時,發生一些悲劇體驗的話,可以利用程式碼來清除back stack entry。
Is this the right way to clean-up Fragment back stack when leaving a deeply nested stack?
http://shareandopen.tumblr.com/post/35328568659/android-clear-all-back-stack
為了好的使用者體驗,希望在程式運作到某一個情境時,清除所有的back stack entry,讓使用者不要在按下back按鍵時,發生一些悲劇體驗的話,可以利用程式碼來清除back stack entry。
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.
// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {
// Get the back stack fragment id.
int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} /* end of for */
2015年9月19日 星期六
【Android】how to open a different fragment on recyclerview OnClick
ref:
http://stackoverflow.com/a/30434250
http://stackoverflow.com/a/30434250
So simplified version, here's my onbindVH:
@Override
public void onBindViewHolder(FeedsViewHolder holder, int position) {
final Feed item = mFeeds.get(position);
holder.textView1.setText(item.getText());
holder.imageView.setImageDrawable(mContext.getResources().getDrawable(item.getImage));
holder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
fragmentJump(item);
}
});
}
here's fragmentJump:
private void fragmentJump(Feed mItemSelected) {
mFragment = new Fragment2();
mBundle = new Bundle();
mBundle.putParcelable("item_selected_key", mItemSelected);
mFragment.setArguments(mBundle);
switchContent(R.id.frag1, mFragment);
}
here's switchContent on the adapter:
public void switchContent(int id, Fragment fragment) {
if (mContext == null)
return;
if (mContext instanceof MainActivity) {
MainActivity mainActivity = (MainActivity) mContext;
Fragment frag = fragment;
mainActivity.switchContent(id, frag);
}
}
and lastly, here's the switchContent on MainActivity:
public void switchContent(int id, Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(id, fragment, fragment.toString());
ft.addToBackStack(null);
ft.commit();
}
I know it can still be simplified, but it works as is. I hope it helps. :)
2015年9月2日 星期三
【Android】Activity and Fragment's Life Cycle
複習一下,兩張圖說明一切。
ref:
http://blog.csdn.net/jewleo/article/details/8919200
http://cheng-min-i-taiwan.blogspot.tw/2012/12/android-fragments.html
http://hankyang.logdown.com/posts/220707-androidandroid-fragament-life-cycle-life-cycle
Android中保存和恢復Fragment狀態的最好方法 (20160531新增)
Activity和Fragement中onSaveInstanceState()的使用詳解 (20160531新增)
ref:
http://blog.csdn.net/jewleo/article/details/8919200
http://cheng-min-i-taiwan.blogspot.tw/2012/12/android-fragments.html
http://hankyang.logdown.com/posts/220707-androidandroid-fragament-life-cycle-life-cycle
Android中保存和恢復Fragment狀態的最好方法 (20160531新增)
Activity和Fragement中onSaveInstanceState()的使用詳解 (20160531新增)
2015年9月1日 星期二
【Android Studio】如何開啟logcat
建立時間:2015-09-01
更新時間:2016-03-04
ref:
更新時間:2016-03-04
ref:
- ref: http://stackoverflow.com/a/16817720
按 Alt + 6 - 記錄一下
- 首先開啟Android Studio(廢話...)
- Tools > Android > Enable ADB Integration選項有勾起,沒有的話就點一下。
- 再次確認Enable ADB Integration選項有勾起。
- Tools > Android > Android Device Monitor 點一下,需要等一下。
- Android Device Monitor 打開後,可以double check 要模擬的device或app name,log會在右下方出現。
- 點選綠色+號(左下角),設定新的過濾器規則。
橘黃色的log可以不用太在意,只是警告;但紅色的log就要特別注意了,是屬於嚴重錯誤。
ref:影片支援
【Android】Different Fragments using different / common menu in Action Bar
ref:
http://stackoverflow.com/a/30556508
http://stackoverflow.com/a/18714611
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1120/2025.html
今天想要在不同的fragment使用特定的menu item,但有些menu item是可以共用。
1.建立一個通用menu.xml
先把需要通用的menu item寫在<group>外,至於範例是想製造每個fragment呈現不同的menu item。
2.建立特定的menu - menu_f1.xml
3.在需要擁有特定menu item的fragment的onCreateView
增加setHasOptionsMenu(true);
來告知這個fragment有另外的OptionsMenu(參考)
4.建立onCreateOptionsMenu(Menu menu, MenuInflater inflater) method,並在onCreateOptionsMenu 引用(inflate)特定的menu,並把通用的menu item顯示設為false。如下所示:
http://stackoverflow.com/a/30556508
http://stackoverflow.com/a/18714611
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1120/2025.html
今天想要在不同的fragment使用特定的menu item,但有些menu item是可以共用。
1.建立一個通用menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <group android:id="@+id/main_menu_group"> <item android:id="@+id/action_refresh" android:icon="@drawable/ic_refresh" android:orderInCategory="90" android:title="@string/action_refresh" app:showAsAction="ifRoom"/> <item android:id="@+id/action_settings" android:orderInCategory="100" android:title="@string/action_settings" app:showAsAction="never"/> </group> </menu>
先把需要通用的menu item寫在<group>外,至於範例是想製造每個fragment呈現不同的menu item。
2.建立特定的menu - menu_f1.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" android:icon="@drawable/ic_search" android:imeOptions="actionSearch" android:inputType="textCapWords" android:orderInCategory="80" android:title="search" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="ifRoom|collapseActionView"/> </menu>
3.在需要擁有特定menu item的fragment的onCreateView
增加setHasOptionsMenu(true);
來告知這個fragment有另外的OptionsMenu(參考)
4.建立onCreateOptionsMenu(Menu menu, MenuInflater inflater) method,並在onCreateOptionsMenu 引用(inflate)特定的menu,並把通用的menu item顯示設為false。如下所示:
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Inflate the menu; this adds items to the action bar if it is present. inflater.inflate(R.menu.menu_air, menu); menu.setGroupVisible(R.id.main_menu_group, false); // menu.findItem(R.id.action_settings).setVisible(false); // menu.findItem(R.id.action_refresh).setVisible(false); super.onCreateOptionsMenu(menu, inflater); }
- 透過1.設定group的方式,將group內的menu item設為不顯示。
- 或者是用menu.findItem(R....).setVisible(false);將個別menu item設為不顯示。
訂閱:
文章 (Atom)