我有一个FragmentActivity
,其中显示了Fragment
defualt。该片段由EditText
,TextView
和自定义DropDown组成,通过扩展AutoCompleteTextView
制作。
如果我的自定义AutoCompleteTextView
已关注或下拉列表已打开,我会更改设备的方向。我得到以下例外:
查找窗口失败
java.lang.IllegalArgumentException:请求的窗口null不存在
如果自定义AutoCompleteTextView
未处于焦点状态,则此方法有效。
我已经尝试通过onSaveInstanceState()
使其他布局获得焦点来消除requestFocus()
中的焦点
我已经在互联网上搜索了这个超过2天的内容,似乎在片段和方向更改的上下文中关于自定义视图之前,没有人遇到过这样的问题。
这是我的FragmentActivity:
public class Balance_Inquiry extends FragmentActivity implements OnTouchListener, EventCallbackListener, DataCallBack,CustomResultReceiver.Receiver {
LinearLayout balInquiryLayout;
FragmentTransaction fragmentTransaction;
FragmentManager fm;
Fragment fr;
//SQLiteDatabase sql;
//ConDb db;
public final static int ACTIVITY_ID = 2;
private Bundle orientationData;
protected void onCreate(Bundle savedInstanceState){
try{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
DisplayMetrics metrics = getResources().getDisplayMetrics();
int screenWidth = (int) (metrics.widthPixels * 0.90);
setContentView(R.layout.common_blank_dialog);
//Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(App.context()));
getWindow().setLayout(screenWidth, LayoutParams.WRAP_CONTENT);
balInquiryLayout = (LinearLayout) findViewById(R.id.dialogtoplayout);
orientationData = savedInstanceState;
if(savedInstanceState == null){
fr = new Balance_Main_Fragment();
fm = getSupportFragmentManager();
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.zoom_enter, R.anim.zoom_exit);
fragmentTransaction.add(R.id.dialogtoplayout, fr,"tag1");
fragmentTransaction.commit();
}
else{
fr = getSupportFragmentManager().findFragmentByTag("tag1");
}
balInquiryLayout.setOnTouchListener(this);
}
catch(Exception e){
e.printStackTrace();
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
balInquiryLayout.requestFocus();
DisableKeyboard.hideKB(v, getApplicationContext());
return false;
}
private AccountBean ab_;
private ValuesBean resp_;
public void show_result(){
try{
fr = new Balance_Result_Fragment();
fm = getSupportFragmentManager();
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.zoom_enter, R.anim.zoom_exit);
fragmentTransaction.add(R.id.dialogtoplayout, fr, "tag2");
fragmentTransaction.commit();
}
catch(Exception e){
e.printStackTrace();
}
}
public void hideResult(){
fr = new Balance_Result_Fragment();
fm = getSupportFragmentManager();
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.zoom_exit,R.anim.zoom_enter);
fragmentTransaction.remove(fr).commit();
//new Balance_Main_Fragment().clearAll();
}
@Override
public void onButtonClicked(int a) {
switch(a){
case 0:
{
hideResult();
try{
fm = getSupportFragmentManager();
Balance_Main_Fragment fre=(Balance_Main_Fragment)getSupportFragmentManager().findFragmentByTag("tag1");
fre.clearAll();
fre.enableButtons();
}
catch(Exception e){
e.printStackTrace();
}
break;
}
case 1:
{
show_result();
break;
}
}
}
@Override
public void passData(String... a) {
}
@Override
public void passData(Object... a) {
try{
this.ab_=(AccountBean) a[0];
this.resp_ = (ValuesBean) a[1];
}
catch(ClassCastException e){
e.printStackTrace();
}
}
@Override
public Object[] getData() {
// TODO Auto-generated method stub
return new Object[]{this.ab_,this.resp_};
}
@Override
public void onBackPressed(){
if(MainExpandActivity.backApprove== true){
if(ParserMain.isMyServiceRunning(MessengerService.class, this)){
NetworkThread.stopServiceNow(Balance_Inquiry.this);
NetworkThread.unBindServicePlz(Balance_Inquiry.this);
}
super.onBackPressed();
}
else{
// do nothing here hehehehe
}
}
@Override
public void onReceiveResult(int resultCode, final Bundle resultData) {
Log.e("activity", "activties onRecieveresul is called");
}
public void onDestroy(){
//NetworkThread.unBindServicePlz(Balance_Inquiry.this);
super.onDestroy();
Log.e("onDestory()", "onDestory() is called");
if(isFinishing()){
NetworkThread.unBindServicePlz(this.getApplicationContext());
NetworkThread.stopServiceNow(this.getApplicationContext());
Log.e("onDestory()", "isFinishing() block");
}
}
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus)
Toast.makeText(Balance_Inquiry.this, "focus gained", Toast.LENGTH_LONG).show();
else
Toast.makeText(Balance_Inquiry.this, "focus lost", Toast.LENGTH_LONG).show();
}
public void onPause(){
Log.e("onPause()", "pause called");
balInquiryLayout.requestFocus();
super.onPause();
}
}
以下是我的Fragment类,只发布相关的片段:
InstantAutoComplete accounts; // custom View
LinearLayout balInq2ndLayout;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
main_view = inflater.inflate(R.layout.fragment_balance1, container,false);
sub = (Button) main_view.findViewById(R.id.sub_bal);
cancel = (Button) main_view.findViewById(R.id.cancel_bal);
accounts = (InstantAutoComplete) main_view.findViewById(R.id.bal_accounts);
mHat = new Handler();
balInq2ndLayout = (LinearLayout) main_view.findViewById(R.id.balInq2ndLayout);
balInq2ndLayout_2 = (LinearLayout) main_view.findViewById(R.id.balInq2ndLayout_2);
macBalance = (TextView) main_view.findViewById(R.id.macbal_balinq);
macBalance.setText(SessionInfo.getBalanceString()+SessionInfo.getMacBalance());
bal_prog = (TextView) main_view.findViewById(R.id.bal_status);
pb = (ProgressBar) main_view.findViewById(R.id.progressBarBalance);
pb.setVisibility(View.GONE);
balInq2ndLayout.requestFocus();
balInq2ndLayout.setOnTouchListener(this);
balInq2ndLayout_2.setOnTouchListener(this);
pin_no = (EditText) main_view.findViewById(R.id.bal_pin);
bal_accountLocked = (EditText) main_view.findViewById(R.id.bal_accountlocked);
bal_accountLocked.setEnabled(false);
bal_accountLocked.setFocusable(false);
bal_accountLocked.setVisibility(View.GONE);
myData = new Bundle();
if(savedInstanceState==null){
bal_accountLocked.setVisibility(View.GONE);
}
else{
pin_no.setText(savedInstanceState.getString("pin"));
if(savedInstanceState.getBoolean("key")){
bal_accountLocked.setVisibility(View.VISIBLE);
bal_accountLocked.setText(savedInstanceState.getString("locked"));
}
if(accounts.getText().toString().length()!=0){
ab = savedInstanceState.getParcelable("ab");
}
if(savedInstanceState.getBoolean("progress")){
pb.setVisibility(View.VISIBLE);
disableButtons();
}
accounts.setText(savedInstanceState.getString("account"));
}
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(App.context()));
final ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.select_dialog_item, ObjectsHolder.ab);
accounts.setAdapter(adapter);
accounts.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
if(accounts.getText().length()==0){
//Toast.makeText(getActivity(), "focus lost", Toast.LENGTH_LONG).show();
accounts.setText(saved1);
DisableKeyboard.disableSoftInputFromAppearing(accounts, getActivity());
}
}
else if(hasFocus){
DisableKeyboard.disableSoftInputFromAppearing(accounts, getActivity());
}
}
});
accounts.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
DisableKeyboard.disableSoftInputFromAppearing(accounts, getActivity());
saved1=DisableKeyboard.showAll(accounts);
if(accounts.getText().toString().length()==0){
bal_accountLocked.setText("");
bal_accountLocked.setVisibility(View.GONE);
}
return false;
}
});
accounts.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id){
Log.e("inside setOnItemSelectedListener", "this is called normally");
//Toast.makeText(arg0.getContext(), "On item click: "+arg0.getItemAtPosition(arg2), 1).show();
ab= (AccountBean) adapter.getItem(position);
//ab = (AccountBean) arg0.getItemAtPosition(arg2);
if(ab==null){
Log.e("ab object", "is null :(");
}
else{
bal_accountLocked.setVisibility(View.VISIBLE);
bal_accountLocked.setText(ab.getAccountNumber());
}
//saved1 = (String) arg0.getItemAtPosition(arg2);
}
});
return main_view;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
balInq2ndLayout.requestFocus();
DisableKeyboard.hideKB(v, getActivity());
return false;
}
public void onSaveInstanceState(Bundle state){
super.onSaveInstanceState(state);
Log.e("onSaved", "onSaved is called");
balInq2ndLayout.requestFocus(); // setting request here to LinearLayout
if(bal_accountLocked.isShown()){
state.putString("locked", bal_accountLocked.getText().toString());
state.putBoolean("key", true);
}
if(ab!=null){
state.putParcelable("ab", ab);
}
state.putString("pin", pin_no.getText().toString());
if(pb.getVisibility() == View.VISIBLE){
state.putBoolean("progress", true);
state.putBoolean("back", true);
}
if(accounts.getText().toString().length()!=0){
state.putString("account", accounts.getText().toString());
}
}
最后这是我的自定义AutoCompleteTextView
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.AutoCompleteTextView;
public class InstantAutoComplete extends AutoCompleteTextView {
String savedTexti2;
public InstantAutoComplete(Context context) {
super(context);
}
public InstantAutoComplete(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public InstantAutoComplete(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
@Override
public boolean enoughToFilter() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
performFiltering(getText(), 0);
showAll();
}
else{
//Toast.makeText(getContext(), "works", 10).show();
//restore();
}
}
public void restore() {
this.setText(savedTexti2);
}
public void showAll() {
savedTexti2 = this.getText().toString();
this.setText("");
this.showDropDown();
}
}
这是完整的StackTrace:
查找窗口失败
java.lang.IllegalArgumentException:请求的窗口null不存在 在com.android.server.WindowManagerService.windowForClientLocked(WindowManagerService.java:9293) 在com.android.server.WindowManagerService.addWindow(WindowManagerService.java:1891) 在com.android.server.WindowManagerService $ Session.add(WindowManagerService.java:6771) 在android.view.IWindowSession $ Stub.onTransact(IWindowSession.java:66) 在com.android.server.WindowManagerService $ Session.onTransact(WindowManagerService.java:6743)
在android.os.Binder.execTransact(Binder.java:288) at dalvik.system.NativeStart.run(Native Method) 尝试使用不是窗口的标记添加窗口:null。中止。
我尝试过很多不同的东西,比如从AutoCompleteTextView中移除焦点,切换焦点......但似乎没有任何效果。如果有人可以帮助我,我会感激,因为我已经访问过stackoverflow的每一个角落,但没有运气。如果有人遇到这个问题并设法解决,请在这里帮助一位兄弟。
- 编辑 -
此问题是在API 8的模拟器中生成的
在JellyBean API 17的模拟器上测试它,它工作正常。没有例外。我想知道它是否只与较低的API有关。必须逐一检查它们。叹息