Hiding Button as a function of position with InfiniteViewPager - java

Just in case somebody is familiar with InfiniteViewPager. I've also started an Issue there, but I was hoping perhaps somebody here might have some insight.
InfiniteViewPager: https://github.com/antonyt/InfiniteViewPager.
The following code sets up my InfiniteViewPager and hides a button depending on the position of the pager. It works, as in the button starts GONE, and appears when you swipe to a new position, but as you swipe back to "position 0" the button reappears. I believe this is because when I swipe back, the position is no longer really "position 0". I get the following in my logcat:
11-23 23:29:49.694 25109-25109/com.app.store D/InfinitePagerAdapter﹕ instantiateItem: real position: 3301
11-23 23:29:49.694 25109-25109/com.app.store D/InfinitePagerAdapter﹕ instantiateItem: virtual position: 1
This is the code for initiating my pager and the OnPageChangeListener.
private void init(Context context) {
View view = inflate(context, R.layout.listview_item, this);
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
ViewPager viewPager;
CustomPagerAdapter adapter;
viewPager = (ViewPager) findViewById(R.id.view_pager);
adapter = new CustomPagerAdapter(context);
PagerAdapter wrappedAdapter = new InfinitePagerAdapter(adapter);
viewPager.setAdapter(wrappedAdapter);
//Hide the button unless showing image
final Button selectButton = (Button) findViewById(R.id.selectButton);
selectButton .setVisibility(GONE);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if(position==0)
selectButton.setVisibility(View.GONE);
else
selectButton.setVisibility(View.VISIBLE);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Basically, I hide the button on "position 0" and show it for every other position using OnPageChangeListener. However, when I return to "position 0", it doesn't recognize "position 0" as "position 0", so it's not hiding the button.
Edit: I've included my XML
<com.antonyt.infiniteviewpager.InfiniteViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="500dp"
android:scaleType="centerCrop">
<android.support.v4.view.PagerTitleStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_viewpagertitlestrip"
android:layout_gravity="top" />
</com.antonyt.infiniteviewpager.InfiniteViewPager>

Use this
if(position % size == 0)
selectButton.setVisibility(View.GONE);
else
selectButton.setVisibility(View.VISIBLE);
where size is total number of actual page.

Related

How to animate view to slide down and push down everything below it?

So I have looked into how to animate fade and drop down/slide up animations of Views using this thread, however it didn't quite work as expected. To begin with, here is the code I use for the animating:
public void toggleAdvancedVisibility(View text) { //text is a clickable textview thats acts as a toggle
int dur = 1000;
final View advView = findViewById(R.id.enc_advanced);
if(advView.getVisibility() == View.GONE && animationDone) {
advView.setVisibility(View.VISIBLE);
advView.setAlpha(0.0f);
//animate fade + drop down
advView.animate()
.setDuration(dur)
.translationY(advView.getHeight())
.alpha(1.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animationDone = true;
}
});
animationDone=false;
}
else if(advView.getVisibility() == View.VISIBLE && animationDone) {
//animate fade + slide up
advView.animate()
.setDuration(dur)
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
advView.setVisibility(View.GONE);
animationDone = true;
}
});
animationDone = false;
}
}
As I said, while there was animation, it didn't act anywhere near as expected.
Problem #1
The view is almost pushed out of visibility. I believe that this is due to the line .translationY(advView.getHeight()) as if I set the location of the view before the animation to advView.setTranslationY(-advView.getHeight()) and then animate .translationY(0) it goes to where it is supposed to.
The obvious problem with this is that while the view is animating, the view "collides" with the view above it before it is done. So how do I properly get this to slide down/up without running into the view above it?
Problem #2
The animation doesn't exactly "push" the view down, which is what I expected. What I mean by this is that the view being animated also has a view below it. I expected the view below it to be pushed down with the animated view. While I haven't tried it yet, I assume this can be simulated by setting the same animation to the view below it, but is there another way of doing it?
I am very new to this animation stuff and manipulating Views like this so any help is appreciated.
I made you a short example and I see it pushes down the rest of the view.
xml:
<LinearLayout 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"
tools:context="com.example.teststuff.MainActivity"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/b1"
android:text="show"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv1"
android:text="Hello World!"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!!!!"/>
and here is the .java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.tv1);
tv2 = (TextView) findViewById(R.id.tv2);
b1 = (Button) findViewById(R.id.b1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (tv1.isShown()){
tv1.startAnimation(slideInAnimation(view));
tv1.setVisibility(View.GONE);
}
else {
tv1.startAnimation(slideOutAnimation(view));
tv1.setVisibility(View.VISIBLE);
}
}
});
}
private TranslateAnimation slideOutAnimation(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,-view.getHeight(),0);
animate.setDuration(500);
animate.setFillAfter(false);
return animate;
}
private TranslateAnimation slideInAnimation(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,0,-view.getHeight());
animate.setDuration(500);
animate.setFillAfter(true);
return animate;
}
It works fine for me.

Views Navigation Using Swipe Gesture android

Based on json ArrayList size I'm creating TextView's.
By using the class Display , made each TextView height and width to cover the entire screen.
MOTTO
Only 1 TextView should be visible on the screen. By swiping it
should move to next view which will again occupy the entire screen.
Swipe down and Swipe up will move the screens i.e., views... swipe left and swipe right should do some other tasks,such as changing activity
Swipe is enabled by using GestureDetector.SimpleOnGestureListener
So far I've tried using ViewFlipper, TextView array to enable switching between TextView.But FAILED :(
Code snippet:
for(int i=0;i<name.size();i++)
{
text = new TextView(MainActivity.this);
text.setText(name.get(i));
text.setId(i);
text.setTextColor(Color.parseColor("#000000"));
text.setLayoutParams(new LinearLayout.LayoutParams(realWidth, realHeight));
text.setGravity(Gravity.CENTER);
text.setTextSize(40);
text.setClickable(true);
vf.addView(text);
/*
//I've tried the following code while using TextView array
myTextViews[i] = text;
myTextViews[i].setId(i);
myTextViews[i].setTextColor(Color.BLACK);
myTextViews[i].setText(name.get(i));
myTextViews[i].setGravity(Gravity.CENTER);
myTextViews[i].setTextSize(40);
myTextViews[i].setLayoutParams(new LinearLayout.LayoutParams(realWidth, realHeight));
myTextViews[i].onWindowFocusChanged(false);
LL.addView(myTextViews[i]);
*/
View lines = new View(getApplicationContext());
lines.setBackgroundColor(Color.parseColor("#000000"));
lines.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
vf.addView(lines);
final int finalI = i;
text.setOnTouchListener(new MainActivity()
{
#Override
public void onSwipeLeft()
{
if (vf.getDisplayedChild() == 0)
Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
else
vf.showNext();
}
#Override
public void onSwipeRight()
{
if (vf.getDisplayedChild() == 0)
Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
else
vf.showPrevious();
}
});
}
Errors:
While using ViewFlipper
E/MessageQueue-JNI﹕ Exception in MessageQueue callback: handleReceiveCallback
Array:
E/InputEventReceiver﹕ Exception dispatching input event. -- java.lang.ArrayIndexOutOfBoundsException
EDIT
I found this Question related to ios. Searching the same for android
I'm trying to develop a app similar to SimplEye
which will be used by Visually disabled people.
For that, I need to control the swipes on the screen so that entire app could be handled only through the help of swipes.
ViewPager , ViewFlipper , SimpleOnGestureListener are not matching the requirement.
Kindly suggest what Technique should be used.
Thank you
bases on the question what i can suggest is use ViewPager
which is alternative for your MOTTO not the solutions of your issue
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
ViewPagerActivity
public class ViewPagerActivity extends Activity {
String text[] = {"A", "B",
"C", "D",
"E", "F",
"G", "H"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyPagerAdapter adapter = new MyPagerAdapter(this, text);
ViewPager myPager = (ViewPager) findViewById(R.id.viewpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
//set Page Change Listner. to get callback on page changed or swiped
myPager .setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Log.e("Page Changed ", " YES ");
/// here you can check & perform on changed
Log.e("Current TextView Text ", text[position]);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
MyPagerAdapter
public class MyPagerAdapter extends PagerAdapter {
Activity activity;
int txtarray[];
public MyPagerAdapter(Activity act, int[] imgArra) {
txtarray = imgArra;
activity = act;
}
public int getCount() {
return txtarray.length;
}
public Object instantiateItem(View collection, int position) {
TextView view = new TextView(activity);
view.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
view.setText(txtarray[position]);
((ViewPager) collection).addView(view, 0);
return view;
}
#Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
#Override
public Parcelable saveState() {
return null;
}
}
Use ViewPager for sliding the views (only by swipe gesture; if you need swipe during time then ViewFlipper is better approach). Make your ViewPager layout_width/layout_height attrs both match_parent (define ViewPager in xml layout not via code). Also make your TextView layout_width/layout_height match_parent too thus you don't need Display class at all.
EDIT. According to latest edition TS needs to handle gesture navigation across the whole app. I suggest the following:
try to not use any widgets which handle gestures (click) by themselves (button, checkbox etc.). Use only uninteractable Views and implement onTouchEvent method inside your Activity which will receive all touch events in this case. In that method you can add any gesture handling you want.
You can create your own ViewGroup implementation and override there onInterceptTouchEvent/onTouchEvent methods and perform there any gesture handling manually.
In both cases you need to create all gesture detection logic by yourself.
These links may be helpful
Creating a simple Gesture Application in Android
How to add our own gestures in android?
Detecting Common Gestures
Never did it but the first link seems to be the most useful. It says that you can firstly create some kind of gesture description and then gesture API can check any gesture performed for match to that description.

Elements inside viewpagers` fragment

I have a problem. I have a viewpager with 3 fragments inside. In first fragment i have some ImageViews.
First of all how make that imageviews visible with timer? I used thise code below but i have error which looks like: variable 'mImageView' is accessed from within inner class, needs to be declared class.
mImageView.setVisibility(View.INVISIBLE);
mImageView.postDelayed(new Runnable() {
public void run() {
mImageView.setVisibility(View.VISIBLE);
}
}, 5000);
How can i solve this problem?
Second I tried to move that elements (ImageViews) by X values when user start scrolling from first fragment to next fragment. It works but when i go to last 3-d fragment app crash. So why it happen?!
MainActivity.java
pager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
// transformation here
final float normalizedPosition = Math.abs(Math.abs(position) - 1);
page.setAlpha(normalizedPosition);
int pageWidth = page.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
page.setAlpha(0);
} else if (position <= 1) { // [-1,1]
ImageView mImageView = (ImageView)findViewById(R.id.imageView2);
mImageView.setTranslationX((float) (-(1 - position) * 1.7 * pageWidth));
mImageView.setVisibility(View.INVISIBLE);
mImageView.postDelayed(new Runnable() {
public void run() {
mImageView.setVisibility(View.VISIBLE);
}
}, 5000);
// The 0.5, 1.5 values you see here are what makes the view move in a different speed.
// The bigger the number, the faster the view will translate.
// The result float is preceded by a minus because the views travel in the opposite direction of the movement.
}
else{ // (1,+Infinity]
// This page is way off-screen to the right.
page.setAlpha(0);
}
}
});
Third: Is it possible to make move elements by circle when user scroll. Need any help!
For your first question, as I said in the comment, you need to make the mImageView variable final
final ImageView mImageView = (ImageView)findViewById(R.id.imageView2);
Then, the null pointer exception, is probably caused (as Blackbelt said), because you're using the activity's findViewById method, and probably the imageView you need is in the fragment view:
final ImageView mImageView = (ImageView) page.findViewById(R.id.imageView2);
And for your 3º question, please explain what you mean by "move by circle", then I'll update my post(if I can) with an answer.
MainActivity.java
// Initialize the ViewPager and set an adapter
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
ViewPagerAdapter.java
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final int PAGES = 3;
private String[] titles={"News", "Organizations", "Map"};
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TabFragment1();
case 1:
return new TabFragment2();
case 2:
return new TabFragment3();
default:
throw new IllegalArgumentException("The item position should be less or equal to:" + PAGES);
}
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
#Override
public int getCount() {
return PAGES;
}
}
As you see for each page I have individual fragment documents. Here below one of them:
public class TabFragment1 extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab_1, container, false);
}
}
fragment_tab_1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/city"
android:id="#+id/imageView2"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>

How to retrieve GridView object after notifyDataSetChanged?

I have search on StackOverflow and other websites but no one can answer to my question.
I have a gridView with items. I have a button to add item to this gridView.Each element on the GridView is a relativeLayout with an Imageview and an EditText.
When i add item to the gridView using the button, I want to get my relativeLayout and request Focus on the editText to set a name on it.
Imagine i have 3 elements in my gridView.
I add element to my ArrayList and call adapter.notifiyDataSetChanged().
The new element is displayed on the grid but when i use getChildCount(), the gridView still has 3 children.
It cause problem because i want to request focus on the last added EditText.
How can i update my gridView object ?
Fragment :
//Get gridView
final GridView gridCat = (GridView) v.findViewById(R.id.gridCategory);
adapter = new GridCategoryAdapter(getActivity(), subcatList);
gridCat.setAdapter(adapter);
gridCat.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SubCategory subcat = subcatList.get(position);
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_middle, SubCategoryFragment.newInstance(subcat.getProducts(), subcat.getName()));
transaction.addToBackStack(null);
transaction.commit();
}
});
Button catAddButton = (Button) v.findViewById(R.id.catAddButton);
catAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "old size gridview : " + gridCat.getChildCount());
subcatList.add(new SubCategory());
Log.d(TAG, "new size list : " + subcatList.size());
adapter.notifyDataSetChanged();
Log.d(TAG, "new size gridview : " + gridCat.getChildCount());
//HERE : childCount is the same !
RelativeLayout rl = (RelativeLayout) gridCat.getChildAt(gridCat.getChildCount()-1);
rl.findViewById(R.id.subcatName).setFocusable(true);
rl.findViewById(R.id.subcatName).setLongClickable(true);
rl.findViewById(R.id.subcatName).requestFocus();
}
});
My Adapter :
public class GridCategoryAdapter extends BaseAdapter {
private static final String TAG = "com.zester.manager.ListViewSizeAndPriceAdapter";
private LayoutInflater mInflater;
private final Context context;
private ArrayList<SubCategory> listSubCat;
private ViewHolder holder;
public GridCategoryAdapter(Context context, ArrayList<SubCategory> values) {
super();
this.context = context;
listSubCat = values;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listSubCat.size();
}
#Override
public Object getItem(int position) {
return listSubCat.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.subcat_view, null);
holder = new ViewHolder();
holder.SubCatName = (EditText) convertView.findViewById(R.id.subcatName);
holder.imageSubCat = (ImageView) convertView.findViewById(R.id.imageSubCatView);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
SubCategory subCat = (SubCategory) getItem(position);
if (subCat != null) {
holder.SubCatName.setText(subCat.getName());
holder.imageSubCat.setImageDrawable(context.getResources().getDrawable(R.drawable.subcat_default));
}
return convertView;
}
static class ViewHolder {
public EditText SubCatName;
public ImageView imageSubCat;
}
}
XML for each item on the gridview :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/imageSubCatView"
android:src="#drawable/subcat_default"
android:layout_centerHorizontal="true"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/subcatName"
android:gravity="center_horizontal"
android:hint="Ex : Bières"
android:layout_marginTop="20dp"
android:layout_below="#+id/imageSubCatView"
android:background="#android:color/transparent"
android:singleLine="true"
android:focusable="false"
android:longClickable="false"/>
Thx a lot !
When i tried to get my RelativeLayout, null is return : RelativeLayout rl = (RelativeLayout) gridCat.getChildAt(gridCat.getCount()-1);
I think your answer is this:
when you add
subcatList.add(new SubCategory());
adapter.notifyDataSetChanged();
to your code it is not guaranteed that new view for them has been created, because it is possible that your gridView has 100 children and you are just looking at children from 7 to 20 , so new child at index 100 has not yet inflated because the getView is called upon request in order to save memory so when there is no need to show the 100th child, why it must be called? so relativelayout for that child is null because it has not inflated.
in catAddButton listener you must not touch any gridview item, because when the button click happens it first runs your listener then scrolls to the end of gridView so still you have problem, what sholud you do?
in class of SubCategory() put variable that indicates it has not shown for the first time. in getView of gridview each time you want to inflate new items look at that variable (in the list of your SubCategory at item list.get(position)) and for example if it is boolean toggle it to false so that means the new object is going to be seen by user. So in this way each time you are going to inflate the view you know that if it is the first time or not, if it is first time your boolean is true else it has already been false. if it is not first time remove focus else put focus by calling reqesFocuse.

Android View getWidth method always returns 0

I have a GridView to put some images in it. What I would like to do is to have the measurements of the GridView such as width and height so that I know what should be the optimal size of images when they are being showed in the getView() method. I want to show only 8 image per row. So say if a device has bigger screen the images will have bigger size instead of adding more image in the row by setting a fixed size for images.
So in the onCreate() method I initialize my custom Adapter and pass the getWidth and getHeight values into it. But they are always zero.
In the xml layout file, gridview was the only view, then I added it to a linearlayout so maybe it atleast return the width and height of its parent...but that is still zero.
Here is the onCreate method of the Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
if (savedInstanceState == null) {
}
int difficulty = getIntent().getExtras()
.getInt(AppConstants.EXTRAS_GAME_DIFFICULTY_LEVEL, 1);
LinearLayout lvg = (LinearLayout) findViewById(R.id.linearForGridGame);
GridView gv = (GridView) findViewById(R.id.gridview);
gv.setAdapter(new CellAdapter(this, difficulty, lvg.getWidth(), lvg.getHeight()));
gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(GameActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
}
Here is the xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearForGridGame">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="128px"
android:numColumns="auto_fit"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="none"
android:gravity="center"
android:choiceMode="none"
android:listSelector="#null"
android:clickable="true" />
</LinearLayout>
And here is the cosntructor of the adapter, where I get width and height always 0:
public CellAdapter(Context context, int difficultyLevel, int parentWidth, int parentHeight)
{
_context = context;
_dificultyLevel = difficultyLevel;
_parentHight = parentHeight;
_parentWidth = parentWidth;
Log.d(TAG, "Received difficulty level " + _dificultyLevel); //OK
Log.d(TAG, "Received parent width " + _parentWidth); //Always 0
Log.d(TAG, "Received parent height " + _parentHight); //Always 0
_cellWidth = (_parentWidth / 6); //Width of image to fill 6 per row
setupGame(_dificultyLevel);
}
You must wait until the view hierarchy is inflated and measured to know the dimensions. Add something like that in onCreate()
final ViewTreeObserver vto = lvg.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (lvg.getWidth() > 10){ // because it may be called before the view is measured and you will still get 0
// here you can get the measured dimensions
ViewTreeObserver obs = pictureImg.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this); // otherwise you're gonne keep getting called
}
}
});
Try doing lvg.getWidth() in onWindowFocusChanged(boolean ) of the activity
I think you have to use LayoutParams, like this:
...
LinearLayout lvg = (LinearLayout) findViewById(R.id.linearForGridGame);
ViewGroup.LayoutParams layoutParams = lvg.getLayoutParams();
GridView gv = (GridView) findViewById(R.id.gridview);
gv.setAdapter(new CellAdapter(this, difficulty, layoutParams.getWidth(), layoutParams.getHeight()));
...
Be sure to import android.view.ViewGroup.LayoutParams .
View layout hasn't occurred at onCreate(), you can see for yourself by subclassing View and observing when onLayout() is called.
Lots of info in this question. A ViewTreeObserver.OnGlobalLayoutListener may be more specific to your desire than onWindowFocusChanged(boolean), as you can target a particular view.
Example from this answer:
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// Ensure you call it only once :
yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// Here you can get the size :)
}
});

Categories