看到別人都可以輸入完EditText1 就跳到EditText2,到底是如何做到的呢?
如果在主要的xml上面有的EditText 要做到這一部分,相信應該不難,網路上也有。
但如果你是要使用AlertDialog跳出一個視窗,該視窗可以輸入東西(EditText),同時又能輸入完跳
下一個的話,如何做呢?
********************************************
本篇是根據這篇教學: 小黑的android教室 來修改的
********************************************
一開始也是就直接複製過去,沒想到居然出現了nullpointer exception!
想了很久才想到原來是因為我的元件不是在activity_main.xml裡面,而一開始的設定
setContentView又是設定activity_main.xml,這就難怪他抓不到了(R.id.元件名稱)!
再解釋更清楚一點,就是當他跳出這個EditText的時候,卻找不到該元件id號,
NullPointerException的例外狀況馬上跳出來。
所以我們需要使用LayoutInflater.inflate這工具來使他(android)明白我們要用的
R.id.元件名是誰/在哪邊(在哪個xml)。在宣告的時候也要這樣用:
mEdit1 = (EditText) login_view.findViewById(R.id.Edit1); 才行
以下是程式碼
Step1;
在onCreate()這邊要初始化一個TextWatcher模組,讓他可以不停監聽
private void InitTextWatcher() {
// 建立文字監聽
TextWatcher mTextWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// 如果字數達到3,取消自己焦點,下一個EditText取得焦點
if (mEdit1.getText().toString().length() == 3) {
mEdit1.clearFocus();
mEdit2.requestFocus();
}
if (mEdit2.getText().toString().length() == 3) {
mEdit2.clearFocus();
mEdit3.requestFocus();
}
if (mEdit3.getText().toString().length() == 3) {
mEdit3.clearFocus();
mEdit4.requestFocus();
}
// 如果字數達到3,取消自己焦點,隱藏虛擬鍵盤
if (mEdit4.getText().toString().length() == 3) {
mEdit4.clearFocus();
IBinder mIBinder = MainActivity.this.getCurrentFocus()
.getWindowToken();
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mInputMethodManager.hideSoftInputFromWindow(mIBinder,
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
};
// 加入文字監聽
mEdit1.addTextChangedListener(mTextWatcher);
mEdit2.addTextChangedListener(mTextWatcher);
mEdit3.addTextChangedListener(mTextWatcher);
mEdit4.addTextChangedListener(mTextWatcher);
}
因為這邊是輸入IP,所以Length設定3。
Step2:
寫一個AlertDialog
public void InitPopup_IP_setting(){
//-----------取得Login Layout reference----------
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
login_view = inflater.inflate(R.layout.ip_setting,null);
//-----------產生登入視窗--------
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Connect");
builder.setMessage("Input Target IP:");
builder.setView(login_view);
dialog = builder.create();
dialog.show();
mEdit1 = (EditText) login_view.findViewById(R.id.Edit1);
mEdit2 = (EditText) login_view.findViewById(R.id.Edit2);
mEdit3 = (EditText) login_view.findViewById(R.id.Edit3);
mEdit4 = (EditText) login_view.findViewById(R.id.Edit4);
InitTextWatcher();
}
**這邊有多一個xml檔就是ip_setting**
ip_setting.xml內容:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/Edit1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="fill"
android:layout_weight="1"
android:digits="0123456789"
android:ems="10"
android:inputType="number"
android:maxLength="3" >
<requestFocus />
</EditText>
<TextView
android:id="@+id/TextView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="." />
<EditText
android:id="@+id/Edit2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:digits="0123456789"
android:ems="10"
android:inputType="number"
android:maxLength="3" />
<TextView
android:id="@+id/TextView06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="." />
<EditText
android:id="@+id/Edit3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:digits="0123456789"
android:ems="10"
android:inputType="number"
android:maxLength="3" />
<TextView
android:id="@+id/TextView04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="." />
<EditText
android:id="@+id/Edit4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:digits="0123456789"
android:ems="10"
android:inputType="number"
android:maxLength="3" />
</LinearLayout>
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="IP_xml_click"
android:text="Enter" />
</LinearLayout>
好了,就這樣讓AlertDialog+TextWatche完美結合了!
2014年11月17日 星期一
2014年10月28日 星期二
[Android] Navigation Drawer的使用(簡易)
如果有看過Facebook app左側或右側可以拉出來的側邊欄, 那麼你已經看過Navigation Drawer了
不過在實際使用上不是那麼的容易(不然就不用寫教學了), 這邊我也研究了兩次,第一次失敗(覺
得太複雜就先做別的),第二次也就是這次才成功。決定把這個有點難的功能寫下來,當然也不
能說是全部都搞懂,就是把會的寫下來,以免以後忘掉。
這個是完成圖-也就是在手機上左側往右邊拉會出現這樣
的ListView選單。要多少選項可以自行調整(超過螢幕的
長度我就沒有測試了),選項一從編號0開始(所以用switch
case 搭配抓取該item的position就可以應用了)
已經大概把Navigation Drawer大概介紹完了(詳細介紹可以找網路),先上程式碼:
(程式碼是下載 TonyCube來修改的)
Step1:
private void InitDrawer(){
fragmentManager = getFragmentManager();
layDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
lstDrawer = (ListView) findViewById(R.id.lst_drawer);
layDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mTitle = mDrawerTitle = getTitle();
drawerToggle = new ActionBarDrawerToggle(
this,
layDrawer,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close) {
@Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
//getActionBar().setTitle(mTitle);
//這邊可以改string內容,關閉時上方標題會改變,如果沒有要標題就不能用這一行
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
//getActionBar().setTitle(R.string.drawer_open);
//這邊可以改string內容,開啟時上方標題會改變,如果沒有要標題就不能用這一行
}
};
drawerToggle.syncState();
layDrawer.setDrawerListener(drawerToggle);
}
首先一定是初始化,因此你需要宣告:
private ActionBarDrawerToggle drawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] drawer_menu;
以免等等會出現錯誤。
findByViewId的部分就是讓程式知道你要的那個元件是在xml裡面的哪一個,
setDrawerShadows的部分很明顯的就是設定陰影(這邊我沒有修改)
mTitle/Title的部分,如果你前面有設定隱藏title,那麼請把這一行+下面setTitle註解掉,因為會出錯
onDrawerOpen/onDrawerClose就是當側邊欄被拉開時/關閉時的動作,裡面可以自由發揮
setDrawerListener就是設一個監聽器,可以隨時抓取動作
Step2:
private void InitDrawerList(){
drawer_menu = this.getResources().getStringArray(R.array.drawer_menu);
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.drawer_list_item, drawer_menu);
List<HashMap<String,String>> lstData = new ArrayList<HashMap<String,String>>();
//多少個item@String Array => for跑幾次
for (int i = 0; i <drawer_menu.length; i++) {
HashMap<String, String> mapValue = new HashMap<String, String>();
//mapValue.put("icon", Integer.toString(R.drawable.ic_launcher));
//要圖示的話才需要加這一行
mapValue.put("title", drawer_menu[i]);
lstData.add(mapValue);
}
SimpleAdapter adapter = new SimpleAdapter(this, lstData, R.layout.drawer_list_item2, new String[]{"icon", "title"}, new int[]{R.id.imgIcon, R.id.txtItem});
lstDrawer.setAdapter(adapter);
//側選單點選監聽器
lstDrawer.setOnItemClickListener(new DrawerItemClickListener());
}
這部分是在設定選項,你有多少個選項for就跑多少次(當然在res-value-Strings-StringArray裡面要
先設定好),旁邊圖示我沒有使用,當然要使用的話也是可以就把mapValue那一行重新恢復即
可。一樣設定監聽器,讓使用者點選時可以馬上反應。
Step3:
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
Fragment fragment = null;
FragmentTransaction fragmentTransaction;
switch (position) {
case 0:
fragment = new Config();
//layDrawer.closeDrawer(lstDrawer);
info_txv.setVisibility(View.INVISIBLE);
main_txv.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.INVISIBLE);
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.Linear_left_drawer, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
break;
case 1:
InitPopup_IP_setting();
break;
case 2:
Self_Test();
break;
default:
//還沒製作的選項,fragment 是 null,直接返回
return;
}
layDrawer.closeDrawer(lstDrawer);
}
這部分監聽器會監聽使用者點選哪個item,會收到position是哪一個,然後再使用selectItem這個函
式處理,這邊使用switch...case。第一個選項是使用一個fragment去取代目前的fragment,由於
fragmentTransaction.addToBackStack(null)無法回去到原本的fragment,因此這個選項有回不去的
風險,請小心使用。第二個選項這邊是設定AlertDialog(),跟NavigationDrawer不相關,不重要因此
就不贅述,第三個選項亦同,default,或是任何你還沒設定的選項請使用return而不是break,否則就
會看到你的app掛點。最後記得要使用closeDrawer()來關閉NavigationDrawer。
NavigationDrawer大概就是這幾部分,然後如果要新增一個頁面(就是讓你點選一個選項會跳到
另一個頁面)的話,在res-layout這邊新增一個xml檔,在src裡面新增一個java檔*如下圖
這樣就可以連結囉!
以上就是NavigationDraw的小心得。 End
不過在實際使用上不是那麼的容易(不然就不用寫教學了), 這邊我也研究了兩次,第一次失敗(覺
得太複雜就先做別的),第二次也就是這次才成功。決定把這個有點難的功能寫下來,當然也不
能說是全部都搞懂,就是把會的寫下來,以免以後忘掉。
這個是完成圖-也就是在手機上左側往右邊拉會出現這樣
的ListView選單。要多少選項可以自行調整(超過螢幕的
長度我就沒有測試了),選項一從編號0開始(所以用switch
case 搭配抓取該item的position就可以應用了)
已經大概把Navigation Drawer大概介紹完了(詳細介紹可以找網路),先上程式碼:
(程式碼是下載 TonyCube來修改的)
Step1:
private void InitDrawer(){
fragmentManager = getFragmentManager();
layDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
lstDrawer = (ListView) findViewById(R.id.lst_drawer);
layDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mTitle = mDrawerTitle = getTitle();
drawerToggle = new ActionBarDrawerToggle(
this,
layDrawer,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close) {
@Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
//getActionBar().setTitle(mTitle);
//這邊可以改string內容,關閉時上方標題會改變,如果沒有要標題就不能用這一行
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
//getActionBar().setTitle(R.string.drawer_open);
//這邊可以改string內容,開啟時上方標題會改變,如果沒有要標題就不能用這一行
}
};
drawerToggle.syncState();
layDrawer.setDrawerListener(drawerToggle);
}
首先一定是初始化,因此你需要宣告:
private ActionBarDrawerToggle drawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] drawer_menu;
以免等等會出現錯誤。
findByViewId的部分就是讓程式知道你要的那個元件是在xml裡面的哪一個,
setDrawerShadows的部分很明顯的就是設定陰影(這邊我沒有修改)
mTitle/Title的部分,如果你前面有設定隱藏title,那麼請把這一行+下面setTitle註解掉,因為會出錯
onDrawerOpen/onDrawerClose就是當側邊欄被拉開時/關閉時的動作,裡面可以自由發揮
setDrawerListener就是設一個監聽器,可以隨時抓取動作
Step2:
private void InitDrawerList(){
drawer_menu = this.getResources().getStringArray(R.array.drawer_menu);
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.drawer_list_item, drawer_menu);
List<HashMap<String,String>> lstData = new ArrayList<HashMap<String,String>>();
//多少個item@String Array => for跑幾次
for (int i = 0; i <drawer_menu.length; i++) {
HashMap<String, String> mapValue = new HashMap<String, String>();
//mapValue.put("icon", Integer.toString(R.drawable.ic_launcher));
//要圖示的話才需要加這一行
mapValue.put("title", drawer_menu[i]);
lstData.add(mapValue);
}
SimpleAdapter adapter = new SimpleAdapter(this, lstData, R.layout.drawer_list_item2, new String[]{"icon", "title"}, new int[]{R.id.imgIcon, R.id.txtItem});
lstDrawer.setAdapter(adapter);
//側選單點選監聽器
lstDrawer.setOnItemClickListener(new DrawerItemClickListener());
}
這部分是在設定選項,你有多少個選項for就跑多少次(當然在res-value-Strings-StringArray裡面要
先設定好),旁邊圖示我沒有使用,當然要使用的話也是可以就把mapValue那一行重新恢復即
可。一樣設定監聽器,讓使用者點選時可以馬上反應。
Step3:
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
Fragment fragment = null;
FragmentTransaction fragmentTransaction;
switch (position) {
case 0:
fragment = new Config();
//layDrawer.closeDrawer(lstDrawer);
info_txv.setVisibility(View.INVISIBLE);
main_txv.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.INVISIBLE);
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.Linear_left_drawer, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
break;
case 1:
InitPopup_IP_setting();
break;
case 2:
Self_Test();
break;
default:
//還沒製作的選項,fragment 是 null,直接返回
return;
}
layDrawer.closeDrawer(lstDrawer);
}
這部分監聽器會監聽使用者點選哪個item,會收到position是哪一個,然後再使用selectItem這個函
式處理,這邊使用switch...case。第一個選項是使用一個fragment去取代目前的fragment,由於
fragmentTransaction.addToBackStack(null)無法回去到原本的fragment,因此這個選項有回不去的
風險,請小心使用。第二個選項這邊是設定AlertDialog(),跟NavigationDrawer不相關,不重要因此
就不贅述,第三個選項亦同,default,或是任何你還沒設定的選項請使用return而不是break,否則就
會看到你的app掛點。最後記得要使用closeDrawer()來關閉NavigationDrawer。
NavigationDrawer大概就是這幾部分,然後如果要新增一個頁面(就是讓你點選一個選項會跳到
另一個頁面)的話,在res-layout這邊新增一個xml檔,在src裡面新增一個java檔*如下圖
這樣就可以連結囉!
以上就是NavigationDraw的小心得。 End
標籤:
[Android App],
使用,
側邊,
側邊欄,
教學,
選項,
應用,
Android,
Navigation Drawer
2014年10月17日 星期五
[Android] Sign & Unsign number (0~256) vs (-128~127)
*不一定是完全正確,可參考*
寫android寫到一個難題,解決了以後把他記下來,以免下次又忘記。
這個問題java也會遇到(其實android根本就是用java寫的....),所以java的也可以稍微參考一下
-----------------------------------------------------------------------------------------------------------------------
在android 裡面byte是沒辦法超過127的,所以如果我們要丟128以上的數字出去,就必須要作調整
不然即使強制轉換: (byte)129 這樣 ,仍然無法使用。java的世界裡面只有
0~127(正數)
---------------------------------
128~255(必須用負數表示)
在255的時候為 -1 因此.....128必須用-128表示(128-256 = -128)
也就是說 if( x > 127){
x = x-256;
}
這樣java才看得懂。
有看到網路上的人用&&FF ,不過那方法我也不太懂,所以就沒用了。
End.
寫android寫到一個難題,解決了以後把他記下來,以免下次又忘記。
這個問題java也會遇到(其實android根本就是用java寫的....),所以java的也可以稍微參考一下
-----------------------------------------------------------------------------------------------------------------------
在android 裡面byte是沒辦法超過127的,所以如果我們要丟128以上的數字出去,就必須要作調整
不然即使強制轉換: (byte)129 這樣 ,仍然無法使用。java的世界裡面只有
0~127(正數)
---------------------------------
128~255(必須用負數表示)
在255的時候為 -1 因此.....128必須用-128表示(128-256 = -128)
也就是說 if( x > 127){
x = x-256;
}
這樣java才看得懂。
有看到網路上的人用&&FF ,不過那方法我也不太懂,所以就沒用了。
End.
2014年10月7日 星期二
[Android] 一些遇到的困難解決方式 跟 經驗談
android 寫到現在終於也快有一個作品出來了,
最常遇到的問題不外乎是import libary是哪一個(整個project掛掉) . R.id無法自動生成 . 明明沒
報錯結果實際run的時候卻出現nullpointer exception....
--------------------------------------------------------------------------------------------------------------------------
這些應該都是android新手常遇到的問題吧?!
解決完畢以後,去Project->clean 即可。同樣你新增一個物件,R.id找不到的時候也是可以
用clean來處理。
最常遇到的問題不外乎是import libary是哪一個(整個project掛掉) . R.id無法自動生成 . 明明沒
報錯結果實際run的時候卻出現nullpointer exception....
--------------------------------------------------------------------------------------------------------------------------
這些應該都是android新手常遇到的問題吧?!
- Library的部分前幾篇有講到,要去properties把某個勾勾去掉
- R.id無法自動生成 問題可能是出在xml檔有Error (API Level太低或太高,xml碼出錯....)
解決完畢以後,去Project->clean 即可。同樣你新增一個物件,R.id找不到的時候也是可以
用clean來處理。
- 明明沒報錯卻有null pointer exception通常是沒有new,或是找不到id,等等.....
這邊特別提一下如果你在"非"main thread想要setText或任何改變UI的行為,都會因為找不
到你要修改的id而產生錯誤,當然即使你有了id number 還是不行,Android只允許在main
thread中修改UI部分。
- 關於Thread / Handler 有些滿不錯的網站:
- 關於Tab / View這類的
https://github.com/
這上面有許多範例程式可以讓你下載回來修改
大概就是這樣,多寫多看囉! over
2014年9月24日 星期三
[Android] ViewPager 遇到在不同xml , 呼叫非setContentView內的R.id.物件 之解決方式
最近在改良Android的APP,先是view flipper,然後現在進階到view pager。
ViewPager可以作出很棒的特效,問題就是在xml方面,如果你要設定物件的話就必須要先
findViewbyId(),這乍聽之下沒甚麼問題,可是假如不是在main.xml檔(主要的xml)的物件呢?
我們使用findViewById()還是可以找到R.id.物件名稱,但只要你一使用的話就會出現錯誤-
java.lang.IllegalState...... NullPointerException....等等。為什麼會出現這樣的錯誤呢?
答案是因為你呼叫的id不在現在的頁面上(Android抓不到他)因此就出現nullpointerException!
在寫的時候也遇到這樣的問題,因此就上網查查看有沒有人也遇到這樣的問題?
發現這篇: 這裡
大意就是說
1.先宣告一個全域變數: private View currentViewPage
2.在 public class MyViewPagerAdapter extends PagerAdapter {} 裡面加入
@Override
public void setPrimaryItem(ViewGroup container, int position,
Object object) {
currentViewPage = (View) object;
}
也就是把現在的position的object轉型成view然後放入currentViewPage(第一步驟設定的變數)裡
面。
3.最後 IP_edt = (EditText) currentViewPage.findViewById(R.id.IP_edt01);
IP_edt.setText("123");
就可以用了喔!(當然IP_edt已經在前面有宣告過了)
希望可以幫助也同樣遇到困難的人!
ViewPager可以作出很棒的特效,問題就是在xml方面,如果你要設定物件的話就必須要先
findViewbyId(),這乍聽之下沒甚麼問題,可是假如不是在main.xml檔(主要的xml)的物件呢?
我們使用findViewById()還是可以找到R.id.物件名稱,但只要你一使用的話就會出現錯誤-
java.lang.IllegalState...... NullPointerException....等等。為什麼會出現這樣的錯誤呢?
答案是因為你呼叫的id不在現在的頁面上(Android抓不到他)因此就出現nullpointerException!
在寫的時候也遇到這樣的問題,因此就上網查查看有沒有人也遇到這樣的問題?
發現這篇: 這裡
大意就是說
1.先宣告一個全域變數: private View currentViewPage
2.在 public class MyViewPagerAdapter extends PagerAdapter {} 裡面加入
@Override
public void setPrimaryItem(ViewGroup container, int position,
Object object) {
currentViewPage = (View) object;
}
也就是把現在的position的object轉型成view然後放入currentViewPage(第一步驟設定的變數)裡
面。
3.最後 IP_edt = (EditText) currentViewPage.findViewById(R.id.IP_edt01);
IP_edt.setText("123");
就可以用了喔!(當然IP_edt已經在前面有宣告過了)
希望可以幫助也同樣遇到困難的人!
訂閱:
文章 (Atom)