创建一个词搜索 android 应用程序。使用片段实现用户界面

Creating a wordsearch android app. Using fragments to implement user interface

我对编码还很陌生,尤其是 Java,所以如果我遗漏了任何基本显而易见的内容,我深表歉意。通俗地回答会有所帮助。

我正在尝试创建一个单词搜索应用程序。一个非常简单的游戏版本,没什么特别的。我制作了一个 gridview 来容纳字母图像以及要进行工作选择的位置,这是顶部片段。底部片段包含正在搜索的字母。

这是包含网格视图的顶部片段的代码。这适用于独立的应用程序,每个字母都是可选的,并且可以进行多项选择。但是,当尝试将其放入片段时 i = new ImageView(TopWordsearchFragment.this); TopWordsearchFragment 会抛出错误 "ImageView(android.content.Context) in ImageView cannot be applied to (com.example.sebastian.multipleselectiongrid.TopWordSearchFragment"

这是我的第一个问题

package com.example.sebastian.multipleselectiongrid;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Checkable;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;

public class TopWordsearchFragment extends Fragment {

GridView mGrid;

TopSectionListener activityCommander;

public interface TopSectionListener{
    public void searchWordsearchWords();
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try{
        activityCommander = (TopSectionListener)activity;
    }catch(ClassCastException e){
        throw new ClassCastException(activity.toString());
    }
}

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.grid_1, container, false);


    mGrid = (GridView) view.findViewById(R.id.myGrid);
    mGrid.setAdapter(new ImageAdapter());
    mGrid.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
    mGrid.setMultiChoiceModeListener(new MultiChoiceModeListener());

    return view;
}

public class ImageAdapter extends BaseAdapter {

    public View getView(int position, View convertView, ViewGroup parent) {
        CheckableLayout l;
        ImageView i;

        if (convertView == null) {
            i = new ImageView(TopWordsearchFragment.this);
            i.setScaleType(ImageView.ScaleType.FIT_XY);
            i.setLayoutParams(new GridView.LayoutParams(85, 85));
            l = new CheckableLayout(TopWordsearchFragment.this);
            l.setLayoutParams(new GridView.LayoutParams(
                    GridView.LayoutParams.WRAP_CONTENT,
                    GridView.LayoutParams.WRAP_CONTENT));
            l.addView(i);
        } else {
            l = (CheckableLayout) convertView;
            i = (ImageView) l.getChildAt(0);
        }


        i.setImageResource(mThumbIds[position]);
        return l;
    }

    public final int getCount() {
        return mThumbIds.length;
    }

    public final Object getItem(int position) {
        return null;
    }

    public final long getItemId(int position) {
        return 0;
    }

    private Integer[] mThumbIds = {
            R.drawable.letter_j, R.drawable.letter_s, R.drawable.letter_o, R.drawable.letter_l, R.drawable.letter_u, R.drawable.letter_t, R.drawable.letter_i, R.drawable.letter_s,
            R.drawable.letter_s, R.drawable.letter_u, R.drawable.letter_n, R.drawable.letter_a, R.drawable.letter_r, R.drawable.letter_u, R.drawable.letter_u, R.drawable.letter_a,
            R.drawable.letter_n, R.drawable.letter_e, R.drawable.letter_p, R.drawable.letter_t, R.drawable.letter_u, R.drawable.letter_n, R.drawable.letter_e, R.drawable.letter_t,
            R.drawable.letter_s, R.drawable.letter_o, R.drawable.letter_n, R.drawable.letter_i, R.drawable.letter_e, R.drawable.letter_i, R.drawable.letter_s, R.drawable.letter_u,
            R.drawable.letter_r, R.drawable.letter_c, R.drawable.letter_e, R.drawable.letter_v, R.drawable.letter_t, R.drawable.letter_r, R.drawable.letter_e, R.drawable.letter_r,
            R.drawable.letter_a, R.drawable.letter_h, R.drawable.letter_t, R.drawable.letter_r, R.drawable.letter_a, R.drawable.letter_e, R.drawable.letter_s, R.drawable.letter_n,
            R.drawable.letter_m, R.drawable.letter_m, R.drawable.letter_e, R.drawable.letter_r, R.drawable.letter_c, R.drawable.letter_u, R.drawable.letter_r, R.drawable.letter_y
    };
}

public class CheckableLayout extends FrameLayout implements Checkable {
    private boolean mChecked;

    public CheckableLayout(Context context) {
        super(context);
    }

    @SuppressWarnings("deprecation")
    public void setChecked(boolean checked) {
        mChecked = checked;
        setBackgroundDrawable(checked ? getResources().getDrawable(
                R.drawable.blue) : null);
    }

    public boolean isChecked() {
        return mChecked;
    }

    public void toggle() {
        setChecked(!mChecked);
    }

}

public class MultiChoiceModeListener implements
        GridView.MultiChoiceModeListener {
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        return true;
    }

    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return true;
    }

    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        return true;
    }

    public void onDestroyActionMode(ActionMode mode) {
    }

    public void onItemCheckedStateChanged(ActionMode mode, int position,
                                          long id, boolean checked) {

    }

}



}

我的第二个问题是碎片不会出现。 BottomSectionFragment 不显示任何编码错误,一旦我 运行 它就会抛出一个错误(我将在下面显示)。这是在注释掉上面的 TopSectionFragment 并从 activity_main.xml 文件中删除该片段之后。

这是 MainActivity.Java 文件

package com.example.sebastian.multipleselectiongrid;


import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
    }

}

下面是 BottomSectionFragment.Java 文件

package com.example.sebastian.multipleselectiongrid;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.app.Activity;

public class BottomSectionFragment extends Fragment {

   TextView word1;
   TextView word2;
   TextView word3;
   TextView word4;
   TextView word5;
   TextView word6;
   TextView word7;
   TextView word8;


    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.bottom_section_fragment, container, false);

        word1 = (TextView) view.findViewById(R.id.word1);
        word2 = (TextView) view.findViewById(R.id.word2);
        word3 = (TextView) view.findViewById(R.id.word3);
        word4 = (TextView) view.findViewById(R.id.word4);
        word5 = (TextView) view.findViewById(R.id.word5);
        word6 = (TextView) view.findViewById(R.id.word6);
        word7 = (TextView) view.findViewById(R.id.word7);
        word8 = (TextView) view.findViewById(R.id.word8);

        return view;

    }
}

当我运行这段代码在一起时,我收到错误FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sebastian.multipleselectiongrid/com.example.sebastian.multipleselectiongrid.MainActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment

并抛出三个原因:Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment

Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class com.example.sebastian.multipleselectiongrid.BottomSectionFragment that is not a Fragment

Caused by: java.lang.ClassCastException

并在每三种情况下指向行setContentView(R.layout.activity_main);

正如我所说,我是编码新手,答案可能非常明显,或者我以错误的方式解决了这个问题。因此,我们将不胜感激任何有用的信息或建议。

编辑: 感谢您的回答。我设法解决了问题 2。在我的 MainActivity class 中,如果我扩展 ActionBarActivity 而不仅仅是 Activity,它工作正常。我检查了 xml 文件,它们的编码完全按照@Kumiho 的建议进行。

至于问题 1,我无法解决在片段中使用此特定代码的问题,因此我将其留在 MainActivity 中(经过适当的编辑)。正如我所希望的那样,两者正在一起工作。现在来实现功能。

再次感谢。

第一个问题:

在构造函数中使用 Fragment 的父级 Activity i = new ImageView(TopWordsearchFragment.this.getActivity());

第二题:

Binary XML file line #8: Error inflating class fragment 指向您的 XML 文件中的语法问题。您可能应该将该文件的内容添加到您的问题中。

  1. 您正在尝试将片段放入 ImageView。这不是它的工作原理。 有视图组和视图。视图只是不包含任何其他视图的视图,而 viewGroups 就像可以包含其他视图或 viewGroups 的容器。 Fragment 可以说是介于 activity 和 viewGroup 之间的东西。 你需要的是上下文。您可以通过 "asking" 您的片段获取它,通过调用 getActivity().
  2. 为您提供 activity
  3. 你的Fragment是在你的Activity的布局文件中声明的吗?如果没有,您需要一个容器,您需要通过获取 Activity 的 fragmentManager 并将片段放入其中以编程方式添加它:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewgroup_activity_layout);
    
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                .add(R.id.container_for_your_fragment, new MyFragment())
                .commit();
        }
    

container_for_your_fragment需要在viewgroup_activity_layout.xml中声明,需要是viewgroup。

使片段可见的另一种方法是在 activity:

的布局中声明它
...
<fragment android:name="com.example.my.FragmentClass"
        android:id="@+id/fragment_id"            
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        ... (further parameters if needed)

/>
...

您将找到更多信息 here

祝你好运。