I'm coding an ebook reader.
For paging I had the smart (stupid ?) idea to use a custom WebView. I changed it's behavior and it scrolls down of 1 page when I swipe left. It works really good expect on one point... The top and bottom text are often cut off. I got the height of my WebView and my font size but then I don't know what to do with that... Is there a way to have no cut off text at the top and at the bottom of my WebView ? It looks like they used the same same technic but with a ScrollView in the opensource PageTurner app but the code is quite complicated, I can't get the code part who could be interesting for me.
public class BookWebView extends WebView {
private final String LOG_TAG = BookView.class.getSimpleName();
private final int SWIPE_LIMIT = 80;
private float startX,diffX;
public BookWebView(Context context) {
super(context);
}
public BookWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BookWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
break;
case MotionEvent.ACTION_UP:
if(Math.abs(diffX) > SWIPE_LIMIT) {
int visibleTextHeight = this.getHeight();
if(diffX < 0) {
Log.d(LOG_TAG,"SCROLLING DOWN");
this.scrollTo(0, getScrollY() + visibleTextHeight);
} else {
Log.d(LOG_TAG,"SCROLLING UP");
this.scrollTo(0, getScrollY() - visibleTextHeight);
}
} else {
Log.d(LOG_TAG, "==== NO SCROLL ====");
return false;
}
break;
case MotionEvent.ACTION_MOVE:
float endX = event.getX();
diffX = endX - startX;
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
return true;
}
}
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BookWebView bwvText = (BookWebView)findViewById(R.id.bwv_text);
String text = "<html><body style=\"text-align:justify\"> %s </body></Html>";
bwvText.loadData(String.format(text,getString(R.string.lorem_ipsum)),"text/html; charset=utf-8", "utf-8");
WebSettings webSettings = bwvText.getSettings();
int fontSize = webSettings.getDefaultFontSize();
bwvText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
bwvText.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
bwvText.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
int webViewHeight = bwvText.getMeasuredHeight();
adjustHeight(webViewHeight,fontSize);
}
});
}
private void adjustHeight(int webViewHeight, int fontSize) {
// Is there something I can do here ?
}
activity_main.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.severalpagestext.MainActivity">
<com.example.android.severalpagestext.BookWebView
android:id="#+id/bwv_text"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
Related
I need to customize default android seekbar to control music player. I know this sounds very simple, but I just don't know how to set up seekbar thumb listener. I want to control music and change icon accordingly to play and pause when user press on seekbar thumb icon. How can I achieve this? I know that this is possible because I previously saw apps like PocketGuide where this functionality is implemented. Here's the screenshot from PocketGuide app
Maybe this helps you. Adjust the code for your needs.
public class SeekbarWithThumbTouch extends SeekBar {
private int scaledTouchSlop = 0;
private float initTouchX = 0;
private boolean thumbPressed = false;
public SeekbarWithThumbTouch(Context context) {
super(context);
init(context);
}
public SeekbarWithThumbTouch(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SeekbarWithThumbTouch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
Drawable thumb = null;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
thumb = getThumb();//works only for API >=16!
if (thumb != null) {
//contains current position of thumb in view as bounds
RectF bounds = new RectF(thumb.getBounds());
thumbPressed = bounds.contains(event.getX(), event.getY());
if (thumbPressed) {
Log.d("Thumb", "pressed");
initTouchX = event.getX();
return true;
}
}
break;
case MotionEvent.ACTION_UP:
if (thumbPressed) {
Log.d("Thumb", "was pressed -- listener call");
thumbPressed = false;
}
break;
case MotionEvent.ACTION_MOVE:
if (thumbPressed) {
if (Math.abs(initTouchX - event.getX()) > scaledTouchSlop) {
initTouchX = 0;
thumbPressed = false;
return super.onTouchEvent(event);
}
Log.d("Thumb", "move blocked");
return true;
}
break;
}
return super.onTouchEvent(event);
}
}
I am using Sliding Activity,
the View is not fitting to the screen, it is hiding behind the Navigation Bar.
I tried ,
<item name="android:fitsSystemWindows">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
but nothing works.
here Snackbar is hiding behind the Navigation Bar:
Hey there best practive would be to use tha NavigationDrawer, but for your problem create a class CustomSlidingMenu which extends SlidingMenu and Override methods like this. Then use the CustomSlidingMenu instead of SlidingMenu and it should work fine
public class CustomSlidingMenu extends SlidingMenu {
private boolean mActionbarOverlay = false;
public CustomSlidingMenu(Context context) {
super(context);
}
public CustomSlidingMenu(Activity activity, int slideStyle) {
super(activity, slideStyle);
}
public CustomSlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#SuppressLint("NewApi")
#Override
protected boolean fitSystemWindows(Rect insets) {
if (mActionbarOverlay) return true;
setMyPadding(insets);
return true;
}
#TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
#Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (mActionbarOverlay) return insets.consumeSystemWindowInsets();
Rect rect = new Rect(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom()
);
setMyPadding(rect);
return insets.consumeSystemWindowInsets();
}
private void setMyPadding(Rect rect) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
switch (manager.getDefaultDisplay().getRotation()) {
case Surface.ROTATION_90:
case Surface.ROTATION_270:
rect.right += getNavBarWidth();
break;
case Surface.ROTATION_180:
rect.top += getNavBarHeight();
break;
default:
rect.bottom += getNavBarHeight();
}
}
setPadding(
rect.left, rect.top, rect.right, rect.bottom
);
}
private int getNavBarWidth() {
return getNavBarDimen("navigation_bar_width");
}
private int getNavBarHeight() {
return getNavBarDimen("navigation_bar_height");
}
private int getNavBarDimen(String resourceString) {
Resources r = getResources();
int id = r.getIdentifier(resourceString, "dimen", "android");
if (id > 0) {
return r.getDimensionPixelSize(id);
} else {
return 0;
}
}
}
I'm assuming that you use AppCompat with my approach, so the reason is that the paddings set by the SlidingMenu are in conflict with the AppCompat configurations and Override them.
I am looking for any good solution to make parallax with two Views.
My first view is Fragment and second is ListView.
Fragment have min height equals 200dp and when I want drag listview to down the fragment will grow.
I wrote some code, but it isn't all I need.
public class MyListView extends ListView implements OnTouchListener {
int touchActionDownY, touchActionMoveY;
int parentHeight;
int initialPosition = -1;
TextView viewToMove;
LinearLayout.LayoutParams params;
public MyListView(Context context) {
super(context);
init();
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init () {
setOnTouchListener(this);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
parentHeight = MeasureSpec.getSize(heightMeasureSpec);
initialPosition = (int) getY();
}
#Override
public boolean onTouch(View v, MotionEvent event) {
int deltaY = 0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchActionDownY = (int)event.getY();
touchActionMoveY = touchActionDownY;
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
deltaY = (int)event.getY() - touchActionMoveY;
touchActionMoveY = (int)event.getY();
if(getFirstVisiblePosition() == 0 && v.getY() < parentHeight && touchActionMoveY > touchActionDownY && deltaY > 0){
params.height = params.height + deltaY;
viewToMove.setLayoutParams(params);
return true;
} else if(v.getY() > 200 && touchActionMoveY < touchActionDownY && deltaY < 0) {
params.height = params.height + deltaY;;
viewToMove.setLayoutParams(params);
return true;
} else {
}
break;
}
return false;
}
public void setViewToMove(TextView v) {
viewToMove = v;
params = (android.widget.LinearLayout.LayoutParams) viewToMove.getLayoutParams();
}
}
In this ListView I need smooth view scroll when user throw list. (View stoped, because method work with ACTION_MOVE).
Any help?
I need interaction with my first fragment.
Parallax should work when only list is draged.
I want to develop my own Accept and Decline buttons for an incoming call. To prevent the call to be accidentally answered or rejected when taking the phone out of the pocket I would like to make a slider style button or something similar. I am, to accept the call is not just to tap on the Accept button. It would be more like sliding the finger from left to right (or opposite) and let the button get wider with the moment. Just like Android does.
Is there any way to make this? Any hint?
I hope to be clear.
How about create an image and slide it to the right (or left) and then send the event to an Activity or any view that you wanna handle the result?
For this, you can created a custom view which implements OnTouchListener :
public class ImageTouchSlider extends RelativeLayout implements View.OnTouchListener {
private Context mContext;
private ImageView mImage;
private int mScreenWidthInPixel;
private int mScreenWidthInDp;
private float mDensity;
private int mPaddingInDp = 15;
private int mPaddingInPixel;
private int mLengthOfSlider;
public interface OnImageSliderChangedListener{
void onChanged();
}
private OnImageSliderChangedListener mOnImageSliderChangedListener;
public ImageTouchSlider(Context context) {
super(context);
mContext = context;
createView();
}
public ImageTouchSlider(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
createView();
}
public ImageTouchSlider(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
createView();
}
public void createView() {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.image_touch_slider, this, true);
mImage = (ImageView) findViewById(R.id.slider_image);
mImage.setOnTouchListener(this);
WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
mDensity = getResources().getDisplayMetrics().density;
float dpWidth = outMetrics.widthPixels / mDensity;
mScreenWidthInPixel = outMetrics.widthPixels;
mScreenWidthInDp = (int) (mScreenWidthInPixel / mDensity);
mLengthOfSlider = (int) (mScreenWidthInDp - mPaddingInDp*2);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
int width = v.getWidth();
float xPos = event.getRawX();
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
// You can add some clicked reaction here.
break;
case MotionEvent.ACTION_MOVE:
if(xPos < (mScreenWidthInPixel - width - mPaddingInDp*mDensity) && xPos > mPaddingInDp*mDensity) {
mOnImageSliderChangedListener.onChanged();
layoutParams.leftMargin = (int) xPos - width / 2;
mImage.setLayoutParams(layoutParams);
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return true;
}
public void setOnImageSliderChangedListener(OnImageSliderChangedListener listener) {
mOnImageSliderChangedListener = listener;
}
} //end of class
image_touch_slider.xml layout :
<?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"
android:orientation="vertical" >
<ImageView
android:id="#+id/slider"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:src="#drawable/your_drawable" />
</RelativeLayout>
You can modify screen width calculation part (my current code is not so clean), and add this view in .xml like this :
<com.your.package.path.ImageTouchSlider
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
In your class, you can find this view :
ImageTouchSlider slider = (ImageTouchSlider) findViewById(R.id.slider);
slider.setOnImageSliderChangedListener(new ImageTouchSlider.OnImageSliderChangedListener() {
#Override
public void onChanged() {
// do something what you want here.
}
});
Hope this can help! :)
If you have your own sliding layout then see this code, might be helpful for you.
public class UnlockBar extends RelativeLayout
{
private OnUnlockListener listener = null;
private TextView text_label = null;
private ImageView img_thumb = null;
private int thumbWidth = 0;
boolean sliding = false;
private int sliderPosition = 0;
int initialSliderPosition = 0;
float initialSlidingX = 0;
public UnlockBar(Context context)
{
super(context);
init(context, null);
}
public UnlockBar(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context, attrs);
}
public UnlockBar(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init(context, attrs);
}
public void setOnUnlockListener(OnUnlockListener listener)
{
this.listener = listener;
}
public void reset()
{
final RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) img_thumb.getLayoutParams();
ValueAnimator animator = ValueAnimator.ofInt(params.leftMargin, 0);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator)
{
params.leftMargin = (Integer) valueAnimator.getAnimatedValue();
img_thumb.requestLayout();
}
});
animator.setDuration(300);
animator.start();
text_label.setAlpha(1f);
}
private void init(Context context, AttributeSet attrs)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.unlock_main, this, true);
// Retrieve layout elements
text_label = (TextView) findViewById(R.id.text_label);
img_thumb = (ImageView) findViewById(R.id.img_thumb);
// Get padding
thumbWidth = dpToPx(80); // 60dp + 2*10dp
}
#Override
#SuppressLint("ClickableViewAccessibility")
public boolean onTouchEvent(MotionEvent event)
{
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
if (event.getX() > sliderPosition && event.getX() < (sliderPosition + thumbWidth))
{
sliding = true;
initialSlidingX = event.getX();
initialSliderPosition = sliderPosition;
}
}
else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_OUTSIDE)
{
if (sliderPosition >= (getMeasuredWidth() - thumbWidth))
{
if (listener != null) listener.onUnlock();
}
else
{
sliding = false;
sliderPosition = 0;
reset();
}
}
else if (event.getAction() == MotionEvent.ACTION_MOVE && sliding)
{
sliderPosition = (int) (initialSliderPosition + (event.getX() - initialSlidingX));
if (sliderPosition <= 0) sliderPosition = 0;
if (sliderPosition >= (getMeasuredWidth() - thumbWidth))
{
sliderPosition = (int) (getMeasuredWidth() - thumbWidth);
}
else
{
int max = (int) (getMeasuredWidth() - thumbWidth);
int progress = (int) (sliderPosition * 100 / (max * 1.0f));
text_label.setAlpha(1f - progress * 0.02f);
}
setMarginLeft(sliderPosition);
}
return true;
}
private void setMarginLeft(int margin)
{
if (img_thumb == null) return;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) img_thumb.getLayoutParams();
params.setMargins(margin, 0, 0, 0);
img_thumb.setLayoutParams(params);
}
private int dpToPx(int dp)
{
float density = getResources().getDisplayMetrics().density;
return Math.round((float)dp * density);
}
public static interface OnUnlockListener {
void onUnlock();
}
}
And just set the listener in main activity
UnlockBar unlock = (UnlockBar) findViewById(R.id.unlock);
// Attach listener
unlock.setOnUnlockListener(new OnUnlockListener() {
#Override
public void onUnlock()
{
Toast.makeText(TestActivity.this, "You've successfully unlocked it !", Toast.LENGTH_LONG).show();
}
});
And draw your own slide_image_layout.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="80dp"
android:layout_width="match_parent"
android:background="#000000"
android:padding="10dp">
<ImageView
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:src="#drawable/unlock_left"
android:contentDescription="#string/unlock_locked" />
<ImageView
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:src="#drawable/unlock_right"
android:contentDescription="#string/unlock_unlocked" />
<TextView
android:id="#+id/text_label"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="#string/unlock_instructions"
android:textColor="#android:color/white"
android:textSize="18sp"
android:textStyle="italic" />
<ImageView
android:id="#+id/img_thumb"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:src="#drawable/unlock_thumb"
android:contentDescription="#string/unlock_thumb" />
</RelativeLayout>
And in your main_layout.xml add this ..
<com.hamondigital.unlock.UnlockBar
android:id="#+id/unlock"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
I am making a grid-based game that will be much larger than the screen, and the user would scroll around in it. I basically put a bunch on ImageViews inside of a custom class that extends a relative layout. The problem is that even though RelativeLayout.LayoutParams is set to the correct size I want (1280*1280). The images are crammed against the sides of the screen and don't extend past it. I have got the scrolling logic working, and when I scroll, I can see it is a rectangle of images the size of one screen. How can I make it so the images extend past the screen?
The class that extends a relative layout:
public class GameGrid extends RelativeLayout {
ImageView[][] subViews;
int rows=0, cols=0, cellsize=0;
int width, height;
//Dragging variables
float startX;
float startY;
float lastX;
float lastY;
boolean touching;
boolean dragging;
int clickedChild;
public GameGrid(Context context) {
super(context);
init();
}
public GameGrid(Context context, int rws, int cls, int clsze) {
super(context);
rows=rws;
cols=cls;
cellsize=clsze;
init();
}
public GameGrid(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GameGrid(Context context, AttributeSet attrs, int defaultStyles) {
super(context, attrs, defaultStyles);
init();
}
public void init() {
rows=10;
cols=10;
cellsize=128;
startX = 0;
startY = 0;
lastX=0;
lastY=0;
touching = false;
dragging = false;
clickedChild = -1;
subViews = new ImageView[cols][rows];
setLayoutParams(new RelativeLayout.LayoutParams(cellsize*cols,cellsize*rows));
width=this.getLayoutParams().width;
height=this.getLayoutParams().height;
this.setMinimumWidth(width);
this.setMinimumHeight(height);
Log.i("info","****************");
Log.i("info","GameGrid Made.");
Log.i("info","width: "+width+"\nheight: "+height);
Log.i("info","****************");
makeGrid();
// this.setOnTouchListener()
}
public boolean getDragging(){
return dragging;
}
public void makeGrid() {
for(int y=0;y<rows;y++){
for(int x=0;x<cols;x++){
ImageView temp = new ImageView(getContext());
temp.setImageResource(R.drawable.water1);
temp.setScaleType(ImageView.ScaleType.FIT_XY);
RelativeLayout.LayoutParams temp2 = new RelativeLayout.LayoutParams(width/cols,height/rows);
if (x == 0 && y == 0){ //If this is the first view being made, set it relative to the parent.
temp2.addRule(RelativeLayout.ALIGN_PARENT_TOP);
temp2.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
}
else if (x == 0){ //If this is in the first column, set it below the one above.
temp2.addRule(RelativeLayout.ALIGN_LEFT,subViews[0][y-1].getId());
temp2.addRule(RelativeLayout.BELOW,subViews[0][y-1].getId());
}
else { //Align the bottom with first one of that row.
temp2.addRule(RelativeLayout.RIGHT_OF,subViews[x-1][y].getId());
temp2.addRule(RelativeLayout.ALIGN_BOTTOM,subViews[0][y].getId());
}
temp.setLayoutParams(temp2);
subViews[x][y]=temp;
subViews[x][y].setId(x+y*cols+1);
// Toast.makeText(getContext(), "" + v.getId(), Toast.LENGTH_SHORT).show();
subViews[x][y].setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v,MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
clickedChild = v.getId();
return false;
}
});
addView(temp);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{ // when the user touches the screen
startX = event.getX();
startY = event.getY();
lastX = event.getX();
lastY = event.getY();
touching = true;
dragging = false;
return true;
}
else if (event.getAction() == MotionEvent.ACTION_MOVE)
{ // when the user moves the touch
if (!dragging)
dragging = true;
int distX = (int)(event.getX()-lastX);
int distY = (int)(event.getY()-lastY);
this.scrollBy(-distX, -distY);
lastX = event.getX();
lastY = event.getY();
return true;
}
else if (event.getAction() == MotionEvent.ACTION_UP)
{ // when the user lifts the touch
if (!dragging){
if (clickedChild>0){
Toast.makeText(getContext(), "getHeight()= " + getHeight(), Toast.LENGTH_SHORT).show();
clickedChild = -1;
}
}
touching = false;
dragging = false;
return true;
}
else if (event.getAction() == MotionEvent.ACTION_CANCEL)
{ // if something gets lost in translation
startX = 0;
startY = 0;
lastX=0;
lastY=0;
touching = false;
dragging = false;
return true;
}
return false;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth, parentHeight);
}
The Activity:
public class Attacktics2 extends Activity {
/** Called when the activity is first created. */
GameGrid grid;
int rows, cols, cellsize;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
}
public void start(View view) {
view.setVisibility(View.GONE);
grid = new GameGrid(this,10,10,128);
setContentView(grid);
}
}
Since you're already doing the heavy lifting of managing all the scrolling, I'd suggest that you implement your entire layout logic yourself and not rely on RelativeLayout. Except for ScrollView and HorizontalScrollView, the stock layout classes are going to restrict their children to be within the parent bounds. Those, in turn, will be restricted to the screen dimensions. If you handle the layout logic yourself, you can position child views so that they extend off screen. It then forms a viewport into a larger grid and can just render those children that are visible within the viewport.