创建一个词搜索 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 文件中的语法问题。您可能应该将该文件的内容添加到您的问题中。
- 您正在尝试将片段放入 ImageView。这不是它的工作原理。
有视图组和视图。视图只是不包含任何其他视图的视图,而 viewGroups 就像可以包含其他视图或 viewGroups 的容器。 Fragment 可以说是介于 activity 和 viewGroup 之间的东西。
你需要的是上下文。您可以通过 "asking" 您的片段获取它,通过调用 getActivity().
为您提供 activity
你的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。
祝你好运。
我对编码还很陌生,尤其是 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 文件中的语法问题。您可能应该将该文件的内容添加到您的问题中。
- 您正在尝试将片段放入 ImageView。这不是它的工作原理。 有视图组和视图。视图只是不包含任何其他视图的视图,而 viewGroups 就像可以包含其他视图或 viewGroups 的容器。 Fragment 可以说是介于 activity 和 viewGroup 之间的东西。 你需要的是上下文。您可以通过 "asking" 您的片段获取它,通过调用 getActivity(). 为您提供 activity
你的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。
祝你好运。