如何更新隐身/屏幕外的视图?

时间:2015-05-10 20:15:57

标签: java android android-arrayadapter android-gridview

我制作了一个包含225个TextView的15x15 GridView,编号为0到224.我可以访问(通过getChildAt(int position))所有适合屏幕的行,即180个TextViews或前12行。我想要做的是调用一个方法(称为playSoE()),将所有TextView的背景更改为不同的颜色。但是,更改最后3行是一个问题,因为它们不在屏幕外。我一直在寻找一种方法来克服这个问题,但我得到的只是“#34;它是不可能的"。如果是这种情况,那么至少我想隐藏的TextViews一旦部分在屏幕上就更新,这样用户就不会注意到差异。有谁知道我将如何实现其中任何一个?

SoE

正如您所看到的,屏幕上有完整/部分的120个TextView,而屏幕右侧有60个,屏幕下方有45个。出于某种原因,将GridView嵌套到HorizontalScrollView是访问右侧TextView所需的全部内容。我尝试对ScrollView和底部的TextViews做同样的事情,但我尝试的没有任何效果。

MainActivity.java:

public class MainActivity extends ActionBarActivity {

    private boolean mIsPlaying;
    private int primesLE;
    private GridView mGridView;
    private ArrayAdapter<TextView> mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mIsPlaying = false;

        ViewGroup.LayoutParams layoutParams;

        primesLE = 225;
        int numOfColumns = (int)Math.round(Math.sqrt((double) primesLE));
        int numOfRows = (int)Math.ceil((double)primesLE/(double)numOfColumns);

        View v1 = findViewById(R.id.title_horizontalScrollView);
        View v2 = v1.findViewById(R.id.relativelayout);
        mGridView = (GridView) v2.findViewById(R.id.mGridView);
        layoutParams = mGridView.getLayoutParams();
        layoutParams.width = 150*numOfColumns; //this is in pixels
        mGridView.setLayoutParams(layoutParams);
        mGridView.setNumColumns(numOfColumns);
        mAdapter = new ImageAdapter(this, android.R.layout.simple_list_item_1, primesLE);
        mGridView.setAdapter(mAdapter);
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    private void playSoE(){

        Log.d("mAdapter.getCount()","" + mAdapter.getCount()); //225
        Log.d("mGridView.getCount()",""+mGridView.getCount()); //225
        Log.d("mGridView.getChildCount()",""+mGridView.getChildCount()); //180


        for(int i = 0; i < 180;i++){ //NPE from 180 or higher
            Log.d("Getting view number",""+i);
            mGridView.getChildAt(i).setBackgroundColor(Color.BLUE);
        }


    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        Log.d("Menu","Button Pressed");
        if (id == R.id.action_settings) {
            return true;
        }

        else if (id == R.id.action_status){
            if(mIsPlaying) {
                mIsPlaying = false;
                item.setIcon(R.drawable.ic_action_play);
                item.setTitle("Play");
                playSoE();
            }
            else {
                mIsPlaying = true;
                item.setIcon(R.drawable.ic_action_pause);
                item.setTitle("Pause");
            }
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

ImageAdapter.java:

public class ImageAdapter extends ArrayAdapter {
    private Context mContext;
    private int mCount;

    public ImageAdapter(Context c, int resource, int count) {
        super(c, resource);
        mContext = c;
        mCount = count;
    }


    public int getCount() {
        return mCount;
    }

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

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

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView textView;

        if (convertView == null) {
            // if it's not recycled, initialize some attributes
            textView = new TextView(mContext);
            textView.setGravity(Gravity.CENTER);
            textView.setLayoutParams(new GridView.LayoutParams(100, 100));

        } else {
            textView = (TextView) convertView;
        }

        textView.setBackgroundColor(Color.RED);
        textView.setText("" + position);
        return textView;
    }

}

activity_main.xml中:

<?xml version="1.0" encoding="utf-8"?>
    <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/title_horizontalScrollView"
        android:fillViewport="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity"
            android:id="@+id/relativelayout">

            <GridView
                android:id="@+id/mGridView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:columnWidth="90dp"
                android:verticalSpacing="10dp"
                android:horizontalSpacing="10dp"
                android:stretchMode="columnWidth"
                android:gravity="center"
            />

        </RelativeLayout>

    </HorizontalScrollView>

menu_main.xml:

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_status"
        android:icon="@drawable/ic_action_play"
        android:title="Play"
        app:showAsAction="always"/>
    <item android:id="@+id/action_stop"
        android:icon="@drawable/ic_action_stop"
        android:title="Stop"
        app:showAsAction="always"/>
    <item android:id="@+id/action_settings"
            android:title="@string/action_settings"
            app:showAsAction="never"  />

    </menu>

1 个答案:

答案 0 :(得分:2)

你有一个非常难看的解决方案:D你应该了解更多关于adaptersrecycled views

的信息

这是你应该做的,

// adapter class
private boolean setBlueBackground = false;

public View getView(int position, View convertView, ViewGroup parent) {
    TextView textView;

    if (convertView == null) {
        // if it's not recycled, initialize some attributes
        textView = new TextView(mContext);
        textView.setGravity(Gravity.CENTER);
        textView.setLayoutParams(new GridView.LayoutParams(100, 100));

    } else {
        textView = (TextView) convertView;
    }

    if(setBlueBackground)
        textView.setBackgroundColor(Color.BLUE);
    else 
        textView.setBackgroundColor(Color.RED);

    textView.setText("" + position);
    return textView;
}

public void setBlueBg(boolean blue) {
    setBlueBackground = blue;
    notifyDataSetChanged();
}

现在你需要做的就是改变颜色了

mAdapter.setBlueBg(true); // or false to make it red

它将取代此

for(int i = 0; i < 180;i++){ //NPE from 180 or higher
    Log.d("Getting view number",""+i);
    mGridView.getChildAt(i).setBackgroundColor(Color.BLUE);
}
你去吧。