Android 遍历 GridView 子元素
Android loop through GridView child elements
我正在创建一个数独应用程序,但遇到了问题 -- 我试图仅隐藏网格上的某些元素,我可以使用 getView() 来实现,但任何时候我使用 EditText 更改值并向下移动键盘,再次调用 getView() 并擦除输入,所以我试图找到解决它的方法。我相信这样做的方法是简单地遍历元素并在 onCreate() 中隐藏某些元素,尽管我在获取视图的任何子元素时遇到问题。我可以使用 getChildAt(i),尽管这只是 returns 数据,而不是视图本身,所以我无法更改可见性。我也尝试过使用以前 Whosebug 答案中的 getChildAt() 解决方案,但它似乎不起作用。
这是我的代码:
主要活动:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.TextView;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
public class MainActivity extends AppCompatActivity {
public GridView gridView;
public String[] items = new String[]{
"5","3","4","6","7","8","9","1","2",
"6","7","2","1","9","5","3","4","8",
"1","9","8","3","4","2","5", "6","7",
"8","5","9","7","6","1","4","2","3",
"4","2","6","8","5","3","7","9","1",
"7","1","3","9","2", "4","8","5","6",
"9","6","1","5","3","7","2","8","4",
"2","8","7","4","1","9","6","3","5",
"3","4","5", "2","8","6","1","7","9"
};
public Boolean[] masker = new Boolean[]{
TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE,
FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE,
TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE,
FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE,
FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE,
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) this.findViewById(R.id.myGridView);
CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items, masker);
gridView.setAdapter(gridAdapter);
final int size = gridAdapter.getCount();
for(int i = 0; i < size; i++) {
ViewGroup gridChild = (ViewGroup) gridView.getChildAt(i);
int childSize = gridChild.getChildCount();
for(int k = 0; k < childSize; k++) {
gridChild.getChildAt(k);
}
}
}
}
自定义网格适配器:
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.TextView;
import static java.lang.Boolean.FALSE;
public class CustomGridAdapter extends BaseAdapter {
private Context context;
private String[] items;
private Boolean[] masker;
private String input;
private EditText t;
LayoutInflater inflater;
public CustomGridAdapter(Context context, String[] items, Boolean[] masker ){
this.context = context;
this.items = items;
this.masker = masker;
inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent){
if(convertView == null){
convertView = inflater.inflate(R.layout.cell, null);
}
t = (EditText) convertView.findViewById(R.id.editCell);
if(masker[position]){
t.setText(items[position]);
t.setEnabled(FALSE);
}else{
t.setText("");
}
if( (position % 9 != 0) && (position % 3 == 0) ){
t.setBackgroundResource(R.drawable.columnborder);
}
if( (position >= 18 && position <= 26) || (position >= 45 && position <= 53) ){
t.setBackgroundResource(R.drawable.rowborder);
}
if( (position == 21 || position == 24 || position == 48 || position == 51 ) ){
t.setBackgroundResource(R.drawable.cornerborder);
}
return convertView;
}
@Override
public int getCount() { return items.length; }
@Override
public Object getItem(int position) { return items[position]; }
@Override
public long getItemId(int position) { return position; }
}
本质上,我只想隐藏数独网格的某些元素,但我认为我不能在 getView() 中这样做,因为它会因为 t.setText(" ");.
有什么建议吗?
你的做法是完全错误的。你不应该改变 GridView 中的视图,除了在 getView 期间。您可以通过其适配器及其保存的数据来操作 GridView。例如,假设您有一个由字符串列表支持的适配器,并且您想要隐藏所有其他字符串。然后你有两个选择 - 更改列表以仅包含所有其他字符串,或者更改它包含的数据以同时包含字符串和可见性,并在 getView 中同时接受这两者。
GridView(或 ListView 或 RecyclerView)的全部要点在于它是一个数据支持的视图,将回收以匹配数据。如果您开始尝试自己操纵视图,那会很糟糕。不要那样做 - 操作数据,然后告诉视图自行更新。
我正在创建一个数独应用程序,但遇到了问题 -- 我试图仅隐藏网格上的某些元素,我可以使用 getView() 来实现,但任何时候我使用 EditText 更改值并向下移动键盘,再次调用 getView() 并擦除输入,所以我试图找到解决它的方法。我相信这样做的方法是简单地遍历元素并在 onCreate() 中隐藏某些元素,尽管我在获取视图的任何子元素时遇到问题。我可以使用 getChildAt(i),尽管这只是 returns 数据,而不是视图本身,所以我无法更改可见性。我也尝试过使用以前 Whosebug 答案中的 getChildAt() 解决方案,但它似乎不起作用。
这是我的代码:
主要活动:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.TextView;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
public class MainActivity extends AppCompatActivity {
public GridView gridView;
public String[] items = new String[]{
"5","3","4","6","7","8","9","1","2",
"6","7","2","1","9","5","3","4","8",
"1","9","8","3","4","2","5", "6","7",
"8","5","9","7","6","1","4","2","3",
"4","2","6","8","5","3","7","9","1",
"7","1","3","9","2", "4","8","5","6",
"9","6","1","5","3","7","2","8","4",
"2","8","7","4","1","9","6","3","5",
"3","4","5", "2","8","6","1","7","9"
};
public Boolean[] masker = new Boolean[]{
TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE,
FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE,
TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE,
TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE,
FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE,
FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE,
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) this.findViewById(R.id.myGridView);
CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items, masker);
gridView.setAdapter(gridAdapter);
final int size = gridAdapter.getCount();
for(int i = 0; i < size; i++) {
ViewGroup gridChild = (ViewGroup) gridView.getChildAt(i);
int childSize = gridChild.getChildCount();
for(int k = 0; k < childSize; k++) {
gridChild.getChildAt(k);
}
}
}
}
自定义网格适配器:
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.TextView;
import static java.lang.Boolean.FALSE;
public class CustomGridAdapter extends BaseAdapter {
private Context context;
private String[] items;
private Boolean[] masker;
private String input;
private EditText t;
LayoutInflater inflater;
public CustomGridAdapter(Context context, String[] items, Boolean[] masker ){
this.context = context;
this.items = items;
this.masker = masker;
inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent){
if(convertView == null){
convertView = inflater.inflate(R.layout.cell, null);
}
t = (EditText) convertView.findViewById(R.id.editCell);
if(masker[position]){
t.setText(items[position]);
t.setEnabled(FALSE);
}else{
t.setText("");
}
if( (position % 9 != 0) && (position % 3 == 0) ){
t.setBackgroundResource(R.drawable.columnborder);
}
if( (position >= 18 && position <= 26) || (position >= 45 && position <= 53) ){
t.setBackgroundResource(R.drawable.rowborder);
}
if( (position == 21 || position == 24 || position == 48 || position == 51 ) ){
t.setBackgroundResource(R.drawable.cornerborder);
}
return convertView;
}
@Override
public int getCount() { return items.length; }
@Override
public Object getItem(int position) { return items[position]; }
@Override
public long getItemId(int position) { return position; }
}
本质上,我只想隐藏数独网格的某些元素,但我认为我不能在 getView() 中这样做,因为它会因为 t.setText(" ");.
有什么建议吗?
你的做法是完全错误的。你不应该改变 GridView 中的视图,除了在 getView 期间。您可以通过其适配器及其保存的数据来操作 GridView。例如,假设您有一个由字符串列表支持的适配器,并且您想要隐藏所有其他字符串。然后你有两个选择 - 更改列表以仅包含所有其他字符串,或者更改它包含的数据以同时包含字符串和可见性,并在 getView 中同时接受这两者。
GridView(或 ListView 或 RecyclerView)的全部要点在于它是一个数据支持的视图,将回收以匹配数据。如果您开始尝试自己操纵视图,那会很糟糕。不要那样做 - 操作数据,然后告诉视图自行更新。