針對你這種狀況,最簡單的一種辦法是,設置兩個TextView的寬度爲固定值,且相等。LinearLayout
是一種線性排列的佈局,佈局中的控件從左到右(或者是從上到下)依次排列。wrap_content
依據其內容分配寬度,「用戶名」和「密碼」因爲內容長度不一樣,致使對應的兩個TextView不等寬,而其後緊跟EditText,這就致使了不對齊。
第2種方法,把LinearLayout中的組件寬度設置爲0dp,而後設置其android:layout_weight
,好比TextView設置爲0.2,EditText設置爲0.8,這兩個控件就會按比例分配整個LinearLayout的寬度。第二個LinearLayout也一樣設置,就能夠保證EditText對齊。
第3種方法,使用RelativeLayout
,經過android:layout_alignLeft="@id/anotherViewId"
設置該View的左邊和指定View的左邊對齊。html
經過代碼動態添加的Fragment,須要在佈局文件中爲 Fragment 添加一個FrameLayout容器,以安排 Fragment 在 activity 視圖中的位置。
在FrameLayout視圖的子組件中,layout_weight
屬性無效。須要經過 layout_gravity
屬性值決定子組件在 FrameLayout 視圖中的位置。
對於水平方向的 LinearLayout,查看 layou_width 和 layout_weight 以決定子組件的寬度。java
若是父視圖是LinearLayout,那麼就能夠直接調用textView.setLayoutParams(params),而後在添加textView到LinearLayout。
若是父視圖是RelativeLayout 或者 FrameLayout,上面的作法無效,解決的辦法是新建一個LinearLayout,而後把textView添加給它,再把這個LinearLayout添加給父視圖。linux
除了配置當前的Activity android:windowSoftInputMode="stateVisible|adjustResize"
外,還須要:listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
android
在 mipmap-[density]
路徑中放app icon圖片,仍然在 drawable-[density]
中放其它圖片。
所以,在Manifest中引用app icon時 android:icon="@mipmap/ic_launcher"
,在其它須要引用圖片的地方仍然用 @drawable/img1
.git
必定是在調用相似以下API的地方,應該賦予的是資源ID,而你卻直接給了一個整數,錯的View.setText(21)
,對的View.setText(R.string.search);
github
實現方式應該是FrameLayout
, 包含一個佔滿所有layout的ImageView,一個底部的TextView,一個右上角的用於顯示數字的某種view。sql
經過一個App: Development.apk 獲取一個Android App APK的全部Activity類名。它是默認安裝在Android模擬器裏的app,目的是方便測試和debug,其中一個功能叫Package Browser
,能夠看到App內的全部的activity.shell
只有當Activity向外聲明瞭本身是能夠處理某些 intent action 時,第三方 app 才能經過 intent 去啓動它,不然將致使崩潰。經過配置文件中的intent過濾器來聲明。
當知道了package name和class name,能夠這樣去啓動第三方的activity:intent.setComponent(new ComponentName(pkg, cls))
數據庫
這應該是不可能的,除非你有系統相機的源碼,修改源碼,而後在系統相機內直接啓動你想啓動的activity。但是爲何想要這樣直接傳遞到新的activity呢?這多麼費力不討好啊。
不管是經過顯示的仍是隱式的intent,啓動第三方的activity,應該總要返回到本身的activity,在onActivityResult()
中處理返回的數據和結果。
因此我猜,你想實現的那種「直接」的效果,應該是在onActivityResult
中拿到圖片後,再次啓動了另外一個新的activity。
我作了一個測試:在A中啓動B;B返回後,在A的onActivityResult中啓動C。視覺上,B直接跳到了C。json
在manifest中配置activity的屬性 android:configChanges="keyboardHidden|orientation|screenSize"
後,就容許Activity本身處理屏幕方向的變化,避免了被系統銷燬。也就是說,相應的生命週期方法不會被調到。
而後爲某一個Activity添加MenuItem,在Item的點擊事件中啓動上面配置的activity;
同時要注意,須要調用searchView.setIconifiedByDefault(false)
,這樣啓動的這個可搜索的activity的searchView纔是展開的。
根據API說明,你的問題的關鍵在於onQueryTextSubmit()
的返回值:只有返回false,才能使SearchView發起一個intent。若是返回true,就認爲這個submit已經被listener本身處理掉了。修改返回值爲fasle,解決問題。
Unfortunately, there is no easy way to change the SearchView icon to a custom drawable, since the theme attribute searchViewSearchIcon is not public. See this answer for details.
爲action bar提供了自定義的佈局,放棄使用android提供的Home鍵android.R.id.home
做爲UpIndicator。而是在這個佈局中添加一個ImageView,這樣就能夠自定義你須要的間距離。而後實現ImageView.OnClickListener
,點擊時返回父activity。
我目前就測試到這兩種狀況會致使重疊:
可能1.經過代碼或者佈局文件,向同一個位置添加了2次Fragment;
設備旋轉時保存Activity的交互狀態: onSaveInstanceState()
;
設備旋轉時保存Fragment的交互狀態: setRetainInstance(true)
;
設備旋轉時保存WebView的數據: android:configChanges="keyboardHidden|orientation|screenSize"
;
設備旋轉時保存在自定義View中繪製的圖形。
SimpleBackPage是enum類型,意圖是經過數字獲取對應的Fragment類:
SimpleBackPage page = SimpleBackPage.getPageValue(pageValue); // 若是pageValue=1,getCls返回的就是FeedBackFragment.class // 若是pageVaule=2,getCls返回的就是AboutFrament.class page.getCls(); public enum SimpleBackPage { FEEDBACK(1, R.string.setting_about, FeedBackFragment.class), ABOUT(2, R.string.setting_about, AboutFrament.class); private SimpleBackPage(int values, int title, Class<?> cls) { this.values = values; this.title = title; this.cls = cls; } public Class<?> getCls() { return cls; }
當拿到Fragment類後,Fragment.class.newInstance()
經過調用該類的無參數構造器,建立並返回該類的一個實例,等價於:new Fragment()
。
this.viewPager.setOnPageChangeListener(this);
追問:「首次進入界面時,顯示第一個頁面時相應的按鈕顏色已經變成點擊後的狀態?」。
追答:首次進入界面時onPageSelected不會被調到。能夠經過viewPager.setCurrentItem(0) 觸發它。
Fragment
是attach在Activity
上的,crash的緣由顯然是你在嘗試調用notifyDataSetChanged
更新fragment時,該fragment的attached activity已經被銷燬了:「IllegalStateException: Activity has been destroyed」。一個workaround是這樣的:
// here you check the value of getActivity() and break up if needed if(getActivity() == null) { return; } // do your stuff to update fragment // ...
我按照你的流程寫了一個demo,復現了你描述的bug現象。
當滑動ViewPager時,致使父fragment視圖被銷燬,即onDestroyView()
被調到,
再次滑動到該父fragment時,重建視圖,即onCreateView()
被調到,ft.add()
被再次調到,再次添加2個子fragment,這就致使了你提到的問題,而並不是是ft.hide()
不起做用。
一個變通的方法能夠解決這個問題,在commit以前先remove全部的子Fragment:
你的問題應該從生命週期和ViewPager的adapter來理解。
Fragment具備和Activity類似的生命週期,而且其生命週期方法由託管它的Activity調用。
當把一些Fragment放入ViewPager時,就須要adapter的支持,以管理這些Fragment。對於經常使用的兩種adapter,FragmentStatePagerAdapter會銷燬掉不須要的fragment,而FragmentPagerAdapter只是銷燬了fragment的視圖。
public class DatePickerDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // 使用不帶theme的構造器,得到的dialog邊框距離屏幕仍有幾毫米的縫隙。 // Dialog dialog = new Dialog(getActivity()); Dialog dialog = new Dialog(getActivity(), R.style.CustomDatePickerDialog); // must be called before set content dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.dialog_datepicker); // 設置寬度爲屏寬、靠近屏幕底部。 Window window = dialog.getWindow(); WindowManager.LayoutParams wlp = window.getAttributes(); wlp.gravity = Gravity.BOTTOM; wlp.width = WindowManager.LayoutParams.MATCH_PARENT; window.setAttributes(wlp); return dialog; }
PendingIntent.getActivity(...)
和 startActivity(intent)
兩種方式啓動的Activity都以一樣的方法獲取extra數據:PendingIntent.getActivity()
打包了一個Context.startActivity()
方法的調用,該方法告訴操做系統『我須要啓動一個Activity』,隨後調用PendingIntent.send()
方法時,操做系統會按照咱們的要求發送原來封裝的intent。
可是使用PendingIntent須要特別注意:
獲取的extra數據極可能是舊的:除非把第4個參數從0改爲PendingIntent.FLAG_UPDATE_CURRENT
.
爲了安全因素,最好只發送顯示的intent.
PendingIntent.getActivity(...)
和 startActivityForResult(...)
兩種方式(第2個參數都是requestCode)啓動的Activity以一樣的方法返回result:setResult(resultCode, intent)
。
而後在void onActivityResult(int requestCode, int resultCode, Intent data)
中根據resultCode
作相應的處理。
總結:仍是讓PendingIntent
作它「字面上」該作的事情爲好,好比經過AlarmManager定時作的任務,經過NotificationManager發送消息到通知欄,一種pending狀態。讓startActivity
啓動應用內的Activity,啓動其它應用:讀取聯繫人、調用攝像頭、發送社交圈,等等,須要馬上響應的任務。
要正肯定義數據,以及初始化adapter的數據。這樣定義數據是不可取的:
rivate String [] groupStr={"第一組","第二組","第三組"}; private String [] childStr={"first","second","third"}; private List<Map<String, String>> groupData = new ArrayList<Map<String, String>>(); private List<Map<String, String>> childData = new ArrayList<Map<String, String>>();
若是刪除了child index=2元素,必然致使你的childData和groupData數量不對等,當adapter試圖爲group2調用getChildrenCount(int groupPosition)
時崩潰。
應該像這樣定義child data: List<List<Map<String, ?>>>
.
緣由是你傳入的context,也就是SumFileActivity
,並無實現你定義的IOnClickListener
。因此沒法強制轉型。既然你在Fragment中實現了接口,那咱們能夠這樣作,註冊一個接口,替代傳入context的辦法,而後還須要作的事件就是,在建立MyDialog的Fragment裏面調用setOnClickListener
.
雖然設置了setOnChildClickListener()
,但點擊child list view item無反應,就我剛纔測試來看,有兩種狀況:
第1種狀況,isChildSelectable()
返回false
,已經被你排除了。
第2種狀況,item的佈局文件中,有控件劫持了點擊事件(ListView
都存在這種狀況)android:focusable="true"
。不配置TextView的這個屬性(由於TextView默認是非聚焦的),或者設置爲false,就能讓item能響應點擊事件。
而像CheckBox, Button, EditText等默認是可聚焦的,若是包含在list item layout內,並且還須要響應item的點擊事件的話,那麼必須設置爲非聚焦。
關於getChildrenCount:
點擊展開GroupItem時,getChildrenCount()
被調到,以返回這個Group的child數量(爲避免出現數組越界的錯誤);而後adapter纔會去調用getChildView()
。
關於getChildView()、getChild()、getGroup():
咱們須要覆寫getChildView()
,以填充視圖,那麼首先要拿到數據,而getChild()
的目的就是拿到存儲在adapter中對應位置的數據。固然,若是你在adapter以外維護了一個child data list,也能夠直接從這個list中取數據。可是getChild()
看起來不是更清楚明瞭嗎?getGroup()
也是一樣的道理,在執行getGroupView()
填充group視圖時,讓你能夠輕鬆地獲取對應的數據。
本質上,ExpandableListAdapter 的getChild(), getGroup()
和 android.widget.Adapter 的 Object getItem(int position)
是一回事兒:『Get the data item associated with the specified position in the data set.』
簡單來講,是爲了複用,避免每次從layout資源文件生成新的視圖(或者是經過代碼生成新的視圖)。好比像ListView
或者GridView
,屏幕上若能顯N個條目,那麼getView
就被調用N次,以提供對應位置的視圖。而複用以前已經生成的視圖,能夠提升效率。
你的代碼已經成功地添加了context menu, 之因此長按無反應,緣由極可能是list item有組件截獲了list的點擊事件。檢查list item的佈局文件,應該能夠看到android:focusable="true"
。把它設置爲false.
錯誤提示信息告訴你問題出在這:『at android.widget.ArrayAdapter.getView(ArrayAdapter.java:369』
你須要瞭解默認的getView方法的實現:
在adapter的構造方法中指定的佈局(android.R.layout.simple_list_item_1)是Android SDK 提供的預約義佈局資源。該佈局擁有一個TextView根元素。而默認的ArrayAdapter<T>.getView(...)實現方法依賴於toString()方法。它首先生成佈局視圖,而後找到指定位置的對象並對其調用toString()方法,最後獲得字符串信息並傳遞給TextView。
因此,我猜問題應該是你傳給Adapter的dataList包含null對象。你應該着重檢查更改adapter數據的代碼。
經過bound service實現後臺下載,這樣,顯示下載狀態的UI組件被銷燬再重建時,經過綁定service就能夠正確顯示下載狀態。固然下載任務必須交給工做線程(好比AsyncTask),由bound service啓動AsyncTask,經過廣播或者接口的方式,應用組件就能夠獲取下載狀態。
針對Android,若是App不在前臺的話,能夠經過service完成:
使用IntentService在後臺抓取服務器的最新數據;
使用AlarmManager和PendingIntent安排服務的運行(設置service查詢的間隔時間);
使用Notification從後臺通知用戶(用戶下拉通知欄後能夠看到詳細信息,點擊後進入App)。
從官方文檔看,應該是爲了得到其餘APP的通知內容從而在本身的鎖屏界面上顯示。you can designate whether a notification from your app is visible on the lock screen.
在4.2的機器上測試,沒法作到。
須要在子線程執行完成的地方,經過主線程的Handler發送一條消息;主線程收到消息後執行。
主線程是UI線程,不要試圖讓UI線程等待某個結果,以後再往下執行,這會致使UI卡頓。UI線程是一直循環的,咱們須要經過消息機制通知UI線程去作一些事情。
你既然想在主線程以外執行recorder.start()
,因此關鍵在於你代碼中的mhandler是誰建立的? 若是是在UI線程中建立的,那麼你經過mhandler.sendMessage
或者post(Runnable)
這些方式,相應的代碼仍將在主線程中執行。
方法1:ScrollView內的子View消耗了它的點擊事件,因此一個解決辦法是,爲它的子View設置setOnClickListener
. (這種辦法,我測試了可行)
方法2:設置全部子View的xml屬性android:clickable="false"
, 而後實現ScrollView的setOnClickListener
方法。(這種方法來自OnClickListener on scrollView,我測試了不行,但解決了別人的問題)
爲數組裏的每個圖片設置一個tag:ImageView.setTag(Objcet tag)
,
在onClick中經過tag識別圖片:((ImageView)v).getTag()
R.layout.menu_frame
包含一個FrameLayout
,這只是一個空的佈局,你能夠把它當作一個Fragment的容器。SlidingMenu提早註冊了一個空的佈局,須要你用本身的menu去替換它:.replace(R.id.menu_frame, new SampleListFragment())
你並無替換,因此看到的是空的。這種作法的本質是把一個包含menu的Fragment視圖添加給Activity。
AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setSingleChoiceItems(R.array.test, 0, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ListView lw = ((AlertDialog) dialog).getListView(); // which表示點擊的條目 Object checkedItem = lw.getAdapter().getItem(which); // 既然你沒有cancel或者ok按鈕,因此須要在點擊item後使dialog消失 dialog.dismiss(); // 更新你的view mButton.setText((String)checkedItem); } }); AlertDialog dialog = builder.create(); dialog.show();
android:alpha="0.5"
alpha property of the view, as a value between 0 (completely transparent) and 1 (completely opaque). Related Methods:
setAlpha(float)
若是你想獲得已顯示的字符個數,或者未顯示的字符個數,那麼其中的關鍵是如何計算每個字符的寬度。而後遍歷這個字符串,當前n個字符寬度總和,超過TextView寬度時,就獲得了已顯示的字符個數。
若是須要存儲用戶配置,好比某些選項是容許仍是禁止,或者是搜索框的歷史記錄,可使用 shared preferences,它是一種存儲key-value的xml文件,能夠實現輕量級數據的永久存儲,使用SharedPreferences類讀寫。
若是須要存儲少許的、簡單的數據,可使用Json文件。
若是須要存儲大量的、複雜的數據,好比一個跑步運動App,持續追蹤用戶的跑步路線,那就須要存儲大量的地理位置數據。而SQLite是一個輕量級的開源跨平臺庫,並具備一套強大的關係型數據庫API可供使用,數據在磁盤上單個文件的形式存在。Android爲SQLite提供了不少類,能夠很方便的完成對數據庫的讀寫操做。
對API存疑的時候,最快的方式是查看API文檔:Passing null will return all columns / all rows for the given URI.
咱們把json文件從新排列,目的是爲了呈現其清晰的嵌套結構。所以,能夠注意到,json包含這些元素:
由[]
括起來的稱之爲數組JSONArray
;
由{}
括起來的稱之爲JSONObject
;
字符串String
;boolean, double, int, long
基本數據類型;
經過JSON Object的方法獲取這些數據,好比string:JSONObject.getString(String name)
而後根據JSON文件的結構,一層一層地解析。
發現你最近也有提Android相關的問題,那我就經過Android ListView item的點擊事件,一種使用頻率很高的view,經過它認識「回調」,可能有助於理解。
好比ListView包含幾個概略信息條目,你想點擊某個條目跳到詳情界面。
mListView.setOnItemClickListener(new OnItemClickListener() { ... });
就已經實現了一個回調(implements a callback interface)。
接下來發生的事情咱們就知道了,點某個條目就跳到其詳情界面。
問題是,誰去調(call)它呢?咱們在實現(implements)這個回調時,爲何必需要override其中的方法呢?
// 當view被點到時,performItemClick就被調到,處理點擊帶給view的變化,除此以外,
// AdapterView還想到了,「若是其它類想在點擊發生時作點兒事情,該怎麼辦呢?」
// 經過接口。
// (1)我來定義接口,把知道的信息(被點到的view、position、id)告訴你;
// (2)你來實現接口,而後把實現的接口告訴我。
OnItemClickListener是接口,不是內部類。接口須要你去implement。
通常的作法是:listview.setOnItemClickListener(mListener)
,而後定義這個listener,並實現其接口規定的方法。
不理解你如此定義 new ListView. OnItemClickListener()
的意圖,但之因此出錯,也許你是沒有導入 import android.widget.AdapterView.OnItemClickListener
。
能夠繼承 Application
類以保存全局的「application state」。由於這些變量是全局的,因此應用的全部組件均可以獲取/更改這些變量。多數狀況下,靜態單例模式能夠提供相同的功能。
shell:/ $ pm list packages shell:/ $ pm list packages -f shell:/ $ dumpsys package com.tencent.mm | grep versionName
這樣的 app 要放在 Android bsp 相應的目錄中,經過 Android.mk 文件編譯,這才能獲取某些特殊權限,這些權限是經過集成編譯器沒法獲取的。
須要在Storyboard中把UIView的類名修改成你自定義的類名:點擊位於Storyboard的CustomView,在右側的選項卡中,點擊Identity Inspector選項卡,而後修改Custom Class;
而後把這個CustomView從Storyboard中拖到ViewController中,創建IBOutlet;
這樣你就擁有了這個CustomView的實例了,而後就能夠修改它的屬性,調用它的方法。
能夠參考這個demo工程。若是你是想經過Storyboard來完成這件事情,就用不着initWithframe,這個方法的目的是用代碼生成一個指定frame的view。
@interface MainViewController () <FristSectionCollectionViewCellDelegate> self.fristSectionCollectionViewCell.delegate = self;
雖然你實現了delegate相應的方法,但若是不給delegate賦值,那麼以下的判斷將爲false:if ([_delegate respondsToSelector:@selector(choseTerm:)])
。一個demo。
嚴格講,上述提示並非出錯的約束,而是多餘的約束,好比設置了上、下邊距,同時又pin了高度,就會致使出現這樣的問題。感受你的問題應該是設置了UIView:0x166ea400高度爲37,而後又設置它等於另外一個UIView:0x16526700寬度的0.0894。這樣就冗餘了。
而排查的方法是,在storyboard中挨個找UIView,37是個很好的切入點,我是這樣作的,很笨。
若是你想實現「不須要拖動就能夠顯示UICollectionView的所有內容」,前提是你爲UICollectionView分配的layout必需要容得下全部的UICollectionViewCell.
若是知足這個前提,好比你想顯示的UICollectionView包含9個cell,每一個cell大小相同,就像一個九宮格。
你必須設置每一個cell的frame size:
// 設置指定位置cell的frame size - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { if (collectionView == self.myCollectionView) { CGRect collectionViewFrame = self.myCollectionView.frame; CGFloat cellWidth = collectionViewFrame.size.width/kCollectionViewCols; CGFloat cellHeight = collectionViewFrame.size.height/kCollectionViewRows; return CGSizeMake(cellWidth, cellHeight); } }
根據父view的frame.origin.x
和frame.size.width
,以及子view的寬度,計算子view的橫座標x,應該是父x + 父w/2 - 子w/2
,而後CGRectMake
。
嚴格講,你這句話『sizeof(arr) =10; 這裏只是把地址傳給sizeof啊』是錯誤的,你傳的是數組名,數組名不等價於地址。
編譯器用數組名標記數組的屬性,好比具備肯定數量的元素。而你說的地址,也就是指針,只是一個標量值。
只有當數組名在表達式中使用時,編譯器纔會爲它產生一個指針常量。而只有如下兩種狀況,纔不被當作指針常量:
sizeof(數組名):返回數組長度(所佔的字節數,不是數組元素個數),而不是指向數組的指針的長度。
&數組名:產生一個指向數組的指針,而不是一個指向某個指針常量的指針。
版權聲明:《分類整理我在 SegmentFault 上針對某些問題做的回答》由 WeiYi.Li 在 2015年11月29日寫做。著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
文章連接:http://li2.me/2015/11/my-sf-a...