【问题标题】:Textview is null on first click but updates on second clickTextview 在第一次单击时为空,但在第二次单击时更新
【发布时间】:2013-01-06 12:20:46
【问题描述】:

它是使用兼容包的小型 Android 2.2 测试应用程序。我正在尝试在列表项选择的另一个活动上更新另一个片段上的文本视图。但问题是,每次第一次点击都会返回空指针异常,并且只有在第二次尝试时,它的文本才会发生变化。我想知道为什么会这样,什么是好的解决方案。

列表活动:-

public class ListActivity extends FragmentActivity implements
    ListFragment.OnItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);
    }

    @Override
    public void onItemSelected(int index) {
        // TODO Auto-generated method stub

        // Check to see if there is a frame in which to embed the
        // detail fragment directly in the containing UI.
        View detailsFrame = findViewById(R.id.detailcontainer);
        if (detailsFrame != null
                && detailsFrame.getVisibility() == View.VISIBLE) {

            DetailFragment detailFragment = (DetailFragment)    getSupportFragmentManager()
                    .findFragmentById(R.id.detailcontainer);

            if (detailFragment == null) {

                detailFragment = new DetailFragment();
            }

            // Execute a transaction, replacing any existing fragment
            // with this one inside the frame.

            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.detailcontainer, detailFragment).commit();

            detailFragment.setTextView(index);

        } else {

            // Otherwise we need to launch a new activity to display
            Intent intent = new Intent(this, DetailActivity.class);
            intent.putExtra("index", index);
            startActivity(intent);

        }
    }
}

列表片段:-

public class ListFragment extends Fragment {

    private OnItemSelectedListener listener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        String[] countries = new String[] { "India", "Pakistan", "Sri Lanka",
                "China", "Bangladesh", "Nepal", "Afghanistan", "North Korea",
                "South Korea", "Japan" };

        View view = inflater.inflate(R.layout.list_fragment, container, false);

        ListView listView = (ListView) view.findViewById(R.id.listView);

        // Populate list
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                this.getActivity(), android.R.layout.simple_list_item_1,
                countries);
        listView.setAdapter(adapter);

        // operation to do when an item is clicked
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Toast.makeText(getActivity(), "ListItem Number " + position,
                        Toast.LENGTH_SHORT).show();


                listener.onItemSelected(position);
            }
        });

        return view;
    }

    // Container Activity must implement this interface
    public interface OnItemSelectedListener {
        public void onItemSelected(int index);
    }

    // To ensure that the host activity implements this interface
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof OnItemSelectedListener) {
            listener = (OnItemSelectedListener) activity;
        } else {
            throw new ClassCastException(activity.toString()
                    + " must implemenet ListFragment.OnItemSelectedListener");
        }
    }

    public void operation(int index) {

        listener.onItemSelected(index);
    }

}

详细活动:-

public class DetailActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DetailFragment details;
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {

            finish();
            return;
        }

        if (savedInstanceState == null) {
            // During initial setup, plug in the details fragment.
            details = new DetailFragment();
            details.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction()
                    .add(android.R.id.content, details).commit();
        }

        Bundle extras = getIntent().getExtras();
        int index = extras.getInt("index");
        try {
            details = (DetailFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.detailfragment);
            details.setTextView(index);

        } catch (NullPointerException ex) {
            ex.getStackTrace();
        }

    }

}

DetailFragment:-

public class DetailFragment extends Fragment {

    String[] capitals;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        if (container == null)
            return null;

        capitals = new String[] { "delhi", "karachi", "colombo", "beijing",
                "dhaka", "katmandu", "Afghanistan", "pyongyang", "seoul",
                "tokyo" };

        View v = inflater.inflate(R.layout.detail_fragment, container, false);

        return v;
    }

    public void setTextView(int index) {

        try {
            TextView view = (TextView) getView().findViewById(R.id.detailView);
            view.setText(capitals[index]);

        } catch (NullPointerException ex) {
            ex.getStackTrace();
        }
    }

    public int getShownIndex() {
        return getArguments().getInt("index", 0);
    }
}

更新:- 我正在添加 detailFragment xml:-

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="@color/lightblue"
android:orientation="vertical" >

<TextView
    android:id="@+id/detailView"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:text="@string/detail_frag" />

</RelativeLayout>

【问题讨论】:

  • 它在以下位置给出 nullpointerException:- TextView view = (TextView) getView().findViewById(R.id.detailView);
  • 什么是索引值
  • 索引值正确。取决于所选项目。
  • 给我看那个 xml (detailView) ??

标签: android android-fragments android-activity textview


【解决方案1】:

不要在 DetailActivity 中做 details.setTextView(index) ,而是在 DetailFragment 的 onActivityCreated 中设置 TextView 的值,同时在 Detailactivity 中的片段 setArgument 方法中传递要设置的值...

  DetailsFragment details = new DetailsFragment();
  details.setArguments(getIntent().getExtras());  // pass the value of text view here

在片段 onActivityCreated 中,通过 getArguments() 获取该值并将其设置在 textview..

EDIT 发送值 Selected 到加载的 Fragment

在列表活动中

  detailFragment = getFragmentbyTag
  if(detailFragment == null)
      Create Fragment and Add it and Set Arguments here as well
  else
      detailFragment.setTextView(value); // fragment already loaded no need to set arguments

如果您想每次都替换而不是添加一次并使用添加/加载的片段,请每次使用 setarguments....并删除先前的片段并添加新片段(使用参数)但最好添加一次并重用在每次点击时删除和添加/替换

【讨论】:

  • 谢谢。这确实解决了部分错误,但我想在横向模式下单击项目时用片段替换我的容器。我如何能够将索引发送到片段并根据单击的项目更新文本。
  • 加载片段并在横向模式下检查 ListActivity 后,检查是否 detailFragment ==null 创建新片段,否则通过其 TAG 获取已加载的片段(添加时可以将 TAG 设置为片段它stackoverflow.com/questions/9363072/android-set-fragment-id)在检索已加载的片段后通过 setTextView 方法更新其文本.. 意思是不要每次都替换片段,只添加一次并在整个过程中使用它并将新文本设置为其中的 TextView,希望我能够传达我的点
【解决方案2】:

更新2

只需在onCreateView() 中初始化您的TextView,无需使用参数化创建DetailFragment,只需在评论中添加即可

检查 details 对象是否为 null,如果 null 像您一样初始化然后调用 setTextView()

if(details==null)
    details = new DetailFragment(index);
else
   setTextView(index);

TextView 里面onCreateView() 并使用了他们的

public class DetailFragment extends Fragment {

    String[] capitals;

    int index;
    private TextView textView;

    public DetailFragment(int index){
        this.index = index;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        if (container == null)
            return null;

        capitals = new String[] { "delhi", "karachi", "colombo", "beijing",
                "dhaka", "katmandu", "Afghanistan", "pyongyang", "seoul",
                "tokyo" };

        View v = inflater.inflate(R.layout.detail_fragment, container, false);
        // Initialize textView
        textView = (TextView) v.findViewById(R.id.detailView);
        setTextView(index); // set value value here for first time
        return v;
    }

    public void setTextView(int index) {
        if(textView!=null)
            textView.setText(capitals[index]); 
    }

    public int getShownIndex() {
        return getArguments().getInt("index", 0);
    }
}

【讨论】:

  • 我收到警告 - 此片段应提供默认构造函数(不带参数的公共构造函数)
  • 第一次点击它也会改变,但是当我选择另一个项目时,它不会改变,因为 settext 只发生在 createView。
  • 你能告诉我每次选择不同的项目时如何更改文本视图吗?
  • 我又回到了同样的问题。第一次单击时 textView 为空,因此不会更新文本。仅从第二次点击开始工作
【解决方案3】:

你试过用这个吗

TextView view = (TextView) findViewById(R.id.detailView);

而不是这个

 TextView view = (TextView) getView().findViewById(R.id.detailView);

【讨论】:

  • 我做不到。它在片段中。我需要风景。
  • 哦,好吧,我没看到它在片段中,对不起!!
猜你喜欢
  • 1970-01-01
  • 2019-11-05
  • 2015-06-03
  • 2022-11-11
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
  • 2012-11-03
  • 2015-07-23
相关资源
最近更新 更多