簡體   English   中英

如何防止我的findViewById方法被過早調用?

[英]How can I prevent my findViewById method from being called too early?

因此,我有一個Dialog ,其中包含一些editText字段(在此信息很重要的情況下,它們分布在3個片段中,由viewpager顯示)。 對於edit操作,我想創建一個對話框,並添加一些值。

目前,我正在嘗試這樣做:

editButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                GeneralSettingsInitialInputDialog GSIID = new GeneralSettingsInitialInputDialog();
                Bundle args = new Bundle();
                args.putString("name", TitleTV.getText().toString());
                args.putString("ip", IPaddressET.getText().toString());
                args.putString("port", PortET.getText().toString());
                args.putString("username", UsernameET.getText().toString());
                args.putString("pass", PasswordET.getText().toString());
                Log.d(tag, args.toString());

                GSIID.setArguments(args);
                GSIID.show(((Activity) context).getFragmentManager(), "GSIID");

這顯示了用於編輯按鈕的onClickListener(包含在recyclerView 。這一點來自我的Adapter )。

之后,我在GSIID dialogFragment的onCreateDialog方法中嘗試了此操作:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = getActivity().getLayoutInflater();
    ma = (MainActivity) getActivity();
    dbHandler = DBHandler.getInstance(getActivity());

    view = inflater.inflate(R.layout.fragment_generalsettingsviewpager, null);

    mPager = (ViewPager) view.findViewById(R.id.pager);
    mPager.setOffscreenPageLimit(3);
    mPagerAdapter = new TestAdapter();
    mPager.setAdapter(mPagerAdapter);


    if (getArguments() != null) {
        ((EditText) view.findViewById(R.id.IDName)).setText(getArguments().getString("name"));
        ((EditText) view.findViewById(R.id.IDIPaddress)).setText(getArguments().getString("ip"));
        ((EditText) view.findViewById(R.id.IDPort)).setText(getArguments().getString("port"));
        ((EditText) view.findViewById(R.id.IDUsername)).setText(getArguments().getString("username"));
        ((EditText) view.findViewById(R.id.IDPassword)).setText(getArguments().getString("pass"));
    }


    // Build Dialog
    final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    builder.setView(view)
            .setTitle("Setup Device")
            .setMessage("Please add all required details for your Raspberry Pi here.")
            .setPositiveButton("Next", null)
            .setNegativeButton("Cancel", null);
    return builder.show();
}

這返回了一個NPE ,表示我試圖在null上使用setText ,因此view.findViewById()返回null。 我以為可以通過將代碼移到onStart()方法來解決此問題,以確保在嘗試對其進行設置之前所有內容都存在,但仍然出現相同的錯誤。

一直以來,我注意到該對話框在錯誤發生之前不會打開,因此我猜findViewById()方法仍然調用得太早,但是我不知道如何解決。

我已經測試過,通過按GSIID對話框上的按鈕(然后打開對話框)來運行上面的代碼,以確保我的代碼沒有損壞。 確實確實有效。

因此,基本上:如何防止該findViewById方法被過早調用?

最有可能是通過在您從此方法返回的視圖上調用查找來在onCreateView()中查找視圖。

您需要在android中掌握此鏈接的生命周期,此鏈接可以幫助您了解生命周期每個步驟中函數調用的順序。

在大多數情況下,您的視圖位於onCreatView()因此將您的findViewById放在此處是合理的,但在其他情況下,應確保視圖已膨脹,然后再調用findViewById

好吧,感謝這篇文章,我的日子得以保存。

基本上,您只需要在自定義PagerAdapter中使用一個方法,該方法PagerAdapter以為您提供的索引返回視圖。

自定義適配器

新增內容: 構造函數 (我相信這就是它的名字)

private View view0 = null;
private View view1 = null;
private View view2 = null;
private View viewError = null;

public TestAdapter(LayoutInflater inflater) {
    view0 = inflater.inflate(R.layout.fragment_generalsettingsinputdialog1, null);
    view1 = inflater.inflate(R.layout.fragment_generalsettingsinputdialog2, null);
    view2 = inflater.inflate(R.layout.fragment_generalsettingsinputdialog3, null);
    viewError = inflater.inflate(R.layout.fragment_viewpagererror, null);
}

更改: InstantiateItem()

@Override
public Object instantiateItem(ViewGroup container, int position) {
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View instView = getViewAtPosition(position);
    instView.setTag("layoutThingy"+position);
    container.addView(instView);
    instView.requestFocus();
    return instView;
}

新增: getViewAtPosition()

public View getViewAtPosition(int position) {
    View view = null;
    switch(position) {
        case 0:
            view = view0;
            break;
        case 1:
            view = view1;
            break;
        case 2:
            view = view2;
            break;
        default:
            view = viewError;
    }
    return view;
}

其他的東西

初始化PagerAdapter時,請確保傳遞LayoutInflater作為參數。 對我來說就像這樣: mPagerAdapter = new TestAdapter(getActivity().getLayoutInflater());

現在,我在onStart()方法中做到了這一點,但我猜您幾乎可以在任何地方做到這一點。

View page1 = mPagerAdapter.getViewAtPosition(0);
View page2 = mPagerAdapter.getViewAtPosition(1);
View page3 = mPagerAdapter.getViewAtPosition(2);

if (getArguments() != null) {
    ((EditText) page1.findViewById(R.id.IDName)).setText(getArguments().getString("name"));
    ((EditText) page2.findViewById(R.id.IDIPaddress)).setText(getArguments().getString("ip"));
    ((EditText) page2.findViewById(R.id.IDPort)).setText(getArguments().getString("port"));
    ((EditText) page3.findViewById(R.id.IDUsername)).setText(getArguments().getString("username"));
    ((EditText) page3.findViewById(R.id.IDPassword)).setText(getArguments().getString("pass"));
}

這樣可以正確找到我所有的EditText ,並且應該可以找到我放在ViewPager 大! 謝謝大家為我提供的幫助,當然也非常感謝cYrixmorten的出色職務

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM