Custom LinearLayout width - weight placing problem - android

I asked another questıon and after, I continued to this problem...
Firstly My first Question: how to Custom Button (has two TextFields) on Android
I extended a class form LinearLayout, and I add two buttons in it(width- fill_parent, weight-1).
But they can't place right. If I use LinearLayout insteadof my customClass, it is working right. What Should I do??
This is my class
public class SplitButtonController extends LinearLayout
implements
OnClickListener {
// Toggle buttons
private Vector<XButton2> buttons;
// Listener
private OnClickListener listener;
public SplitButtonController(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.xbutton2, this);
}
public SplitButtonController(Context context) {
super(context);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
init();
}
/**
* Initialize the toggle buttons (set images and listeners). It's
* responsibility of the user call this method after he add a ne
*/
public void init() {
buttons = new Vector<XButton2>();
addLayoutButtons();
changeButtonsImage();
setListeners();
}
private void addLayoutButtons() {
int n = getChildCount();
for (int i = 0; i < n; i++) {
View v = getChildAt(i);
if (v instanceof XButton2) {
buttons.add((XButton2) v);
}
}
}
private void changeButtonsImage() {
if (buttons.size() > 1) {
buttons.get(0)
.setBackgroundResource(
com.matriksdata.bavul.R.drawable.schedule_left_button_drawable);
for (int i = 1; i < buttons.size() - 1; i++) {
// buttons.get(i).setBackgroundResource(R.drawable.schedule_left_button_drawable);
}
buttons.get(buttons.size() - 1)
.setBackgroundResource(
com.matriksdata.bavul.R.drawable.schedule_right_button_drawable);
} else {
// TODO:set an image with rounded sides
}
}
private void setListeners() {
for (int i = 0; i < buttons.size(); i++) {
buttons.get(i).setOnClickListener(this);
buttons.get(i).setFocusable(true);
}
}
#Override
public void onClick(View v) {
for (int i = 0; i < buttons.size(); i++) {
XButton2 b = buttons.get(i);
b.setChecked(v == b);
}
}
}

The buttons you added to your SplitButtonController are XButton2, and in your constructor, you are inflating R.layout.xbutton2. This will cause an empty "XButton2" added to your SplitButtonController layout. You don't need to inflate anything if you want to create (or extend) a simple LinearLayout. Then your SplitButtonController code should look like following:
public class SplitButtonController extends LinearLayout
implements
OnClickListener {
// Toggle buttons
private Vector<XButton2> buttons;
// Listener
private OnClickListener listener;
public SplitButtonController(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
init();
}
/**
* Initialize the toggle buttons (set images and listeners). It's
* responsibility of the user call this method after he add a ne
*/
public void init() {
buttons = new Vector<XButton2>();
addLayoutButtons();
changeButtonsImage();
setListeners();
}
private void addLayoutButtons() {
int n = getChildCount();
for (int i = 0; i < n; i++) {
View v = getChildAt(i);
if (v instanceof XButton2) {
buttons.add((XButton2) v);
}
}
}
private void changeButtonsImage() {
if (buttons.size() > 1) {
buttons.get(0)
.setBackgroundResource(
com.matriksdata.bavul.R.drawable.schedule_left_button_drawable);
for (int i = 1; i < buttons.size() - 1; i++) {
// buttons.get(i).setBackgroundResource(R.drawable.schedule_left_button_drawable);
}
buttons.get(buttons.size() - 1)
.setBackgroundResource(
com.matriksdata.bavul.R.drawable.schedule_right_button_drawable);
} else {
// TODO:set an image with rounded sides
}
}
private void setListeners() {
for (int i = 0; i < buttons.size(); i++) {
buttons.get(i).setOnClickListener(this);
buttons.get(i).setFocusable(true);
}
}
#Override
public void onClick(View v) {
for (int i = 0; i < buttons.size(); i++) {
XButton2 b = buttons.get(i);
b.setChecked(v == b);
}
}
}

Related

Click listener is not working on surface view inside frame layout

I have read out many questions but I don't get the answer to mine.
So I am posting this new question.
I am working on a live streaming app. Basically I want to change the surface view size on click event like Whatsapp video calling.
I have two scenarios:-
Scenario 1:- One is relative layout which contains a surface view and there is a frame layout which also contains a surface view and I want to exchange when click event happens but the Click event listener is not working.
XML file
<FrameLayout
android:id="#+id/liveStreaming_videoAndControlsContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black">
<com.sos.GD_Live.utils.liveUtils.VideoGridContainer
android:id="#+id/liveStreaming_videoContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.sos.GD_Live.utils.liveUtils.VideoGridContainer>
<FrameLayout
android:id="#+id/videoChat_localVideoRender"
android:layout_marginBottom="130dp"
android:layout_marginRight="20dp"
android:layout_width="100dp"
android:onClick="frameclick"
android:visibility="visible"
android:layout_height="150dp"
android:layout_gravity="bottom|right"
/>
Its parent layout is also a frame layout
public class VideoGridContainer extends RelativeLayout implements Runnable {
private static final int MAX_USER = 4;
private static final int STAT_LEFT_MARGIN = 34;
private static final int STAT_TEXT_SIZE = 10;
private SparseArray<ViewGroup> mUserViewList = new SparseArray<>(MAX_USER);
private List<Integer> mUidList = new ArrayList<>(MAX_USER);
private Handler mHandler;
private int mStatMarginBottom;
private VideoViewEventListener mEventListener;
public VideoGridContainer(Context context) {
super(context);
init();
}
public VideoGridContainer(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public VideoGridContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mHandler = new Handler(getContext().getMainLooper());
}
public void addUserVideoSurface(int uid, SurfaceView surface, boolean isLocal) {
if (surface == null) {
return;
}
int id = -1;
if (isLocal) {
if (mUidList.contains(0)) {
mUidList.remove((Integer) 0);
mUserViewList.remove(0);
}
if (mUidList.size() == MAX_USER) {
mUidList.remove(0);
mUserViewList.remove(0);
}
id = 0;
} else {
if (mUidList.contains(uid)) {
mUidList.remove((Integer) uid);
mUserViewList.remove(uid);
}
if (mUidList.size() < MAX_USER) {
id = uid;
}
}
if (id == 0) mUidList.add(0, uid);
else mUidList.add(uid);
if (id != -1) {
mUserViewList.append(uid, createVideoView(surface));
requestGridLayout();
}
}
private ViewGroup createVideoView(SurfaceView surface) {
RelativeLayout layout = new RelativeLayout(getContext());
layout.setId(surface.hashCode());
LayoutParams videoLayoutParams =
new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
layout.addView(surface, videoLayoutParams);
TextView text = new TextView(getContext());
text.setId(layout.hashCode());
LayoutParams textParams =
new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
textParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
textParams.bottomMargin = mStatMarginBottom;
textParams.leftMargin = STAT_LEFT_MARGIN;
text.setTextColor(Color.WHITE);
text.setTextSize(STAT_TEXT_SIZE);
layout.addView(text, textParams);
return layout;
}
public void removeUserVideo(int uid, boolean isLocal) {
if (isLocal && mUidList.contains(0)) {
mUidList.remove((Integer) 0);
mUserViewList.remove(0);
} else if (mUidList.contains(uid)) {
mUidList.remove((Integer) uid);
mUserViewList.remove(uid);
}
requestGridLayout();
if (getChildCount() == 0) {
mHandler.removeCallbacks(this);
}
}
private void requestGridLayout() {
removeAllViews();
layout(mUidList.size());
}
private void layout(int size) {
LayoutParams[] params = getParams(size);
for (int i = 0; i < size; i++) {
addView(mUserViewList.get(mUidList.get(i)), params[i]);
}
}
private LayoutParams[] getParams(int size) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
LayoutParams[] array =
new LayoutParams[size];
for (int i = 0; i < size; i++) {
if (i == 0) {
array[0] = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
array[0].addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
array[0].addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
} else if (i == 1) {
array[1] = new LayoutParams(width, height / 2);
array[0].height = array[1].height;
array[1].addRule(RelativeLayout.BELOW, mUserViewList.get(mUidList.get(0)).getId());
array[1].addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
} else if (i == 2) {
array[i] = new LayoutParams(width / 2, height / 2);
array[i - 1].width = array[i].width;
array[i].addRule(RelativeLayout.RIGHT_OF, mUserViewList.get(mUidList.get(i - 1)).getId());
array[i].addRule(RelativeLayout.ALIGN_TOP, mUserViewList.get(mUidList.get(i - 1)).getId());
} else if (i == 3) {
array[i] = new LayoutParams(width / 2, height / 2);
array[0].width = width / 2;
array[1].addRule(RelativeLayout.BELOW, 0);
array[1].addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
array[1].addRule(RelativeLayout.RIGHT_OF, mUserViewList.get(mUidList.get(0)).getId());
array[1].addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
array[2].addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
array[2].addRule(RelativeLayout.RIGHT_OF, 0);
array[2].addRule(RelativeLayout.ALIGN_TOP, 0);
array[2].addRule(RelativeLayout.BELOW, mUserViewList.get(mUidList.get(0)).getId());
array[3].addRule(RelativeLayout.BELOW, mUserViewList.get(mUidList.get(1)).getId());
array[3].addRule(RelativeLayout.RIGHT_OF, mUserViewList.get(mUidList.get(2)).getId());
}
}
return array;
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
clearAllVideo();
}
private void clearAllVideo() {
removeAllViews();
mUserViewList.clear();
mUidList.clear();
mHandler.removeCallbacks(this);
}
#Override
public void run() {
}
public void setItemEventHandler(VideoViewEventListener listener) {
this.mEventListener = listener;
}
}
This code where in Java file, when I added surface view for both of the layouts
mVideoLayout = findViewById(R.id.liveStreaming_videoContainer);
mVideoLayout.addUserVideoSurface(0, surface, true);
SurfaceView surface = prepareRtcVideo(remotehost, false);
surface.setZOrderMediaOverlay(true);
mCameraBtn.setVisibility(View.VISIBLE);
remotehostlist.add(remotehost);
surface.setZOrderOnTop(true);
runOnUiThread(() -> {
surface.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Toast.makeText(LiveStreamingActivity.this, "it's good", Toast.LENGTH_SHORT).show();
return true;
}
});
surface.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(LiveStreamingActivity.this, "it's good", Toast.LENGTH_SHORT).show();
}
});
});
mLayoutSmallView.addView(surface);
mLayoutSmallView.setVisibility(View.VISIBLE);
mLayoutSmallView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Toast.makeText(LiveStreamingActivity.this, "Focus changed", Toast.LENGTH_SHORT).show();
}
});
mRtcEngine.setupLocalVideo(new VideoCanvas(surface, VideoCanvas.RENDER_MODE_HIDDEN, 0));
mRtcEngine.enableVideo();
I have already tried onclick in XML, ontouchlistener, onfocuschange listener. But no one of them is working for it. Also tried is focusable.
The problem is I am unable to click the frame layout named mLayoutSmallView.
I want to switch the surface views when it is clicked.

How to create ItemView for GridLayout

I tried to create Grid Layout for this I used below code. But in that code I don't know what is ItemView and how to implement it. When I put this code in my project I get error can not resolve symbol "ItemView". I got this code from below link -
https://stackoverflow.com/a/36143314/5726392
public class PrivateSeatViews extends FrameLayout implements View.OnClickListener {
private GridLayout mGridView;
private int mRowsCount;
private int mColsCount;
private int mCellSpace;
private OnItemClickListener mOnItemClickListener;
public PrivateSeatViews(Context context) {
super(context);
init(context, null);
}
// other constructors
private void init(Context context, AttributeSet attrs) {
// default values
View layout = inflate(getContext(), R.layout.grid_layout, null);
mGridView = (GridLayout) layout.findViewById(R.id.Lower);
mGridView.setRowCount(mRowsCount);
mGridView.setColumnCount(mColsCount);
mGridView.post(new Runnable() {
#Override
public void run() {
int width = getMeasuredWidth() / getColumnsCount();
int height = getMeasuredHeight() / getRowsCount();
for (int i = 0; i < getRowsCount(); i++) {
for (int j = 0; j < getColumnsCount(); j++) {
GridLayout.LayoutParams params = (GridLayout.LayoutParams) getChildAt(i, j).getL;
params.width = width;
params.height = height;
getChildAt(i, j).setLayoutParams(params);
}
}
}
});
addView(layout);
}
// this method allows to dinamically create grid
public void buildChildren(int rowsCount, int colsCount) {
mRowsCount = rowsCount;
mColsCount = colsCount;
mGridView.setRowCount(mRowsCount);
mGridView.setColumnCount(mColsCount);
buildChildren();
}
public void buildChildren() {
for (int i = 0; i < getRowsCount(); i++) {
for (int j = 0; j < getColumnsCount(); j++) {
ItemView1 view = new ItemView1(getContext(), i, j);
view.setOnClickListener(this);
mGridView.addView(view);
}
}
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
public ItemView getChildAt(int rowIndex, int columnIndex) {
int index = (getColumnsCount() * rowIndex) + columnIndex;
return (ItemView) mGridView.getChildAt(index);
}
public boolean isTouchOn(int rowIndex, int columnIndex) {
return getChildAt(rowIndex, columnIndex).isTouchOn();
}
public int getColumnsCount() {
return mGridView.getColumnCount();
}
public int getRowsCount() {
return mGridView.getRowCount();
}
#Override
public void onClick(View v) {
if (v instanceof ItemView) {
ItemView view = (ItemView) v;
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(view);
}
}
}
public interface OnItemClickListener {
void onItemClick(ItemView view);
}
}
The best way i found to create the GridView is to use RecyclerView with the GridLayouy manager. Adapter implementations is the same as for normal RecyclerView
You can create GridLayout manager like this
//3 is the row span
GridLayoutManager a = new GridLayoutManager(this, 3);
This will help you to improve performance and create your view with the ViewHolder pattern
If you never used RecyclerView you can see a fine example here

GridLayout with view dynamic get row/column

I just followed this tutorial, to create a custom View as an item of a GridLayout.
That's my CustomView
public class RowView extends View{
boolean touchOn;
boolean mDownTouch = false;
private OnToggledListener toggledListener;
int _IdRow = 0;
int _IdColumn = 0;
public RowView(Context context, int Rows, int Columns) {
super(context);
this._IdRow = Rows;
this._IdColumn = Columns;
init();
}
public RowView(Context context) {
super(context);
init();
}
public RowView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
touchOn = false;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
#Override
protected void onDraw(Canvas canvas) {
if (touchOn) {
canvas.drawColor(Color.RED);
} else {
canvas.drawColor(Color.GRAY);
}
}
//onClick not possible to use on custom View so, onTouchEvent is the solution
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()) {
//if Click
case MotionEvent.ACTION_DOWN:
touchOn = !touchOn;
invalidate();
if(toggledListener != null){
toggledListener.OnToggled(this, touchOn);
}
mDownTouch = true;
return true;
case MotionEvent.ACTION_UP:
if (mDownTouch) {
mDownTouch = false;
performClick();
return true;
}
}
return false;
}
#Override
public boolean performClick() {
super.performClick();
return true;
}
public void setOnToggledListener(OnToggledListener listener){
toggledListener = listener;
}
public int get_IdRow() {
return _IdRow;
}
public int get_IdColumn() {
return _IdColumn;
}
On this class I can detect when user clicks on an item of GridLayout and change it to another color, that's ok.
But the problem comes at the time to create this :
This is my MainActivity where I show the GridLayout :
int numOfCol = mGridLayout.getColumnCount();
int numOfRow = mGridLayout.getRowCount();
mRowViews = new RowView[numOfCol*numOfRow];
for(int yPos=0; yPos<numOfRow; yPos++){
for(int xPos=0; xPos<numOfCol; xPos++){
RowView tView = new RowView(this, xPos, yPos);
tView.setOnToggledListener(this);
mRowViews[yPos*numOfCol + xPos] = tView;
mGridLayout.addView(tView);
}
}
mGridLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
#Override
public void onGlobalLayout() {
final int MARGIN = 5;
int pWidth = mGridLayout.getWidth();
int pHeight = mGridLayout.getHeight();
int numOfCol = mGridLayout.getColumnCount();
int numOfRow = mGridLayout.getRowCount();
int w = pWidth/numOfCol;
int h = pHeight/numOfRow;
for(int yPos=0; yPos<numOfRow; yPos++){
for(int xPos=0; xPos<numOfCol; xPos++){
GridLayout.LayoutParams params =
(GridLayout.LayoutParams)mRowViews[yPos*numOfCol + xPos].getLayoutParams();
params.width = w - 2*MARGIN;
params.height = h - 2*MARGIN;
params.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);
mRowViews[yPos*numOfCol + xPos].setLayoutParams(params);
}
}
}});
Also there is a method of the Interface OnToggledListener that gives to me the row and column of my GridLayout when an item of it is clicked :
#Override
public void OnToggled(MyView v, boolean touchOn) {
//get the id string
String idString = v.get_IdRow() + ":" + v.get_IdColumn();
}
I'd like to avoid to create that mGridLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() because it fills on the screen thing that I don't want... I tried to put GridLayout 6x6 with android:layout_height="400dp" and it only show 3x3 and this is the LogCat message
D/android.widget.GridLayout: vertical constraints: y6-y0>=1749, y6-y5<=291, y5-y4<=291, y4-y3<=291, y3-y2<=291, y2-y1<=291, y1-y0<=291 are inconsistent; permanently removing: y6-y5<=291.
I'd like to do something like GridLayout[row][colum] to get the color of background and then do stuff, but I'm not able to find this solution.
For simplifying, you can implement a custom Board view wrapping the GridLayout and related logic. Below I report a possible approach.
Expectation here is to have an ItemView for representing one single cell in the board.
public class Board extends FrameLayout implements View.OnClickListener {
private GridLayout mGridView;
private int mRowsCount;
private int mColsCount;
private int mCellSpace;
private OnItemClickListener mOnItemClickListener;
public Board(Context context) {
super(context);
init(context, null);
}
// other constructors
private void init(Context context, AttributeSet attrs) {
// default values
mRowsCount = 1;
mColsCount = 1;
View layout = inflate(getContext(), R.layout.view_lights_board, null);
mGridView = (GridLayout) layout.findViewById(R.id.view_grid);
mGridView.setRowCount(mRowsCount);
mGridView.setColumnCount(mColsCount);
mGridView.post(new Runnable() {
#Override
public void run() {
int width = getMeasuredWidth() / getColumnsCount();
int height = getMeasuredHeight() / getRowsCount();
for (int i = 0; i < getRowsCount(); i++) {
for (int j = 0; j < getColumnsCount(); j++) {
GridLayout.LayoutParams params = (GridLayout.LayoutParams)
getChildAt(i, j).getLayoutParams();
params.width = width;
params.height = height;
getChildAt(i, j).setLayoutParams(params);
}
}
}
});
addView(layout);
}
// this method allows to dinamically create grid
public void buildChildren(int rowsCount, int colsCount) {
mRowsCount = rowsCount;
mColsCount = colsCount;
mGridView.setRowCount(mRowsCount);
mGridView.setColumnCount(mColsCount);
buildChildren();
}
public void buildChildren() {
for (int i = 0; i < getRowsCount(); i++) {
for (int j = 0; j < getColumnsCount(); j++) {
ItemView view = new ItemView(getContext(), i, j);
view.setOnClickListener(this);
mGridView.addView(view);
}
}
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
}
public ItemView getChildAt(int rowIndex, int columnIndex) {
int index = (getColumnsCount() * rowIndex) + columnIndex;
return (ItemView) mGridView.getChildAt(index);
}
public boolean isTouchOn(int rowIndex, int columnIndex) {
return getChildAt(rowIndex, columnIndex).isTouchOn();
}
public int getColumnsCount() {
return mGridView.getColumnCount();
}
public int getRowsCount() {
return mGridView.getRowCount();
}
#Override
public void onClick(View v) {
if (v instanceof ItemView) {
ItemView view = (ItemView) v;
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(view);
}
}
}
public interface OnItemClickListener {
void onItemClick(ItemView view);
}
}
In your Activity layout you will have something like this (here I assume your app package is com.android.example):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.android.example.Board
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="400dp" />
</FrameLayout>
And this is possible implementation of the Activity:
public class MainActivity extends AppCompatActivity implements LightsOutBoard.OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Board board = (Board) findViewById(R.id.grid);
board.setOnItemClickListener(this);
board.buildChildren(3, 3);
}
#Override
public void onItemClick(ItemView view) {
String text = view.getRowIndex() + " - " + view.getColumnIndex();
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
}
Hope this could help.

Regarding http://stackoverflow.com/questions/2381560/how-to-group-a-3x3-grid-of-radio-buttons

I tried to use the code provided as the first answer on the website that appears in the title. I can't make it work, although I tried to modify it. The problem is that when I check a radio button other than the first radio button, they both stay checked.
Question is: when do the addView methods get called?
Also, here is my version of the code, I hope somebody can show me my mistakes:
public class ToggleButtonGroupTableLayout extends TableLayout implements OnClickListener {
private static final String TAG = "ToggleButtonGroupTableLayout";
private ToggleButtonGroupTableLayout radGroup;
private RadioButton activeRadioButton;
/**
* #param context
*/
public ToggleButtonGroupTableLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
/**
* #param context
* #param attrs
*/
public ToggleButtonGroupTableLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
public void onClick(View v) {
final RadioButton rb = (RadioButton) v;
radGroup = (ToggleButtonGroupTableLayout) findViewById(R.id.radGroup1);
int activeRadioButtonId = radGroup.getCheckedRadioButtonId(v);
Log.i(TAG,"FIRST " + activeRadioButtonId);
// if (activeRadioButtonId != -1 && activeRadioButton != null ) {
// activeRadioButton.setChecked(false);
// }
rb.setChecked(true);
//activeRadioButton = rb;
if (activeRadioButtonId != -1 && activeRadioButton != null ) {
activeRadioButton = (RadioButton) findViewById(activeRadioButtonId);
activeRadioButton.setChecked(false);
}
else
Log.i(TAG,"" + activeRadioButton + " " + activeRadioButtonId);
}
/* (non-Javadoc)
* #see android.widget.TableLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams)
*/
#Override
public void addView(View child, int index,
android.view.ViewGroup.LayoutParams params) {
super.addView(child, index, params);
setChildrenOnClickListener((TableLayout)child);
}
/* (non-Javadoc)
* #see android.widget.TableLayout#addView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
#Override
public void addView(View child, android.view.ViewGroup.LayoutParams params) {
super.addView(child, params);
setChildrenOnClickListener((TableLayout)child);
}
private void setChildrenOnClickListener(TableLayout tl) {
final int c = tl.getChildCount();
for (int i=0; i < c; i++) {
final View v = tl.getChildAt(i);
if ( v instanceof TableRow ) {
final int c1 = ((TableRow) v).getChildCount();
for (int j = 0; j < c1; j++) {
View v1 = ((TableRow) v).getChildAt(j);
if (v1 instanceof RadioButton)
v1.setOnClickListener(this);
}
}
}
}
public int getCheckedRadioButtonId(View v) {
if ( activeRadioButton != null ) {
return activeRadioButton.getId();
}
return -1;
}
Just modify setChildrenOnClickListener:
private void setChildrenOnClickListener(TableRow tr) {
final int c = tr.getChildCount();
for (int i=0; i < c; i++) {
final View v = tr.getChildAt(i);
if (v instanceof RadioButton) {
v.setOnClickListener(this);
if (((RadioButton) v).isChecked())
activeRadioButton = (RadioButton) v;
}
}
}
I know this question was asked while ago, but anyway I think i know the answer..
The issue you're experiening is because you have more radioButtons with no, or same ID. You need to set them different id's in order for them to work.
Hope this will help someone.

How to make automatic onClick and update mark image in Gridview

The first question that I have is that I have downloaded from the Internet MarkableImageView class to add a marker to an image I have already selected. The class is as follows:
public class MarkableImageView extends ImageView {
// Por defecto falso
private boolean checked = false;
public MarkableImageView(Context context) {
super(context);
}
public MarkableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarkableImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setChecked(boolean checked) {
this.checked = checked;
invalidate();
}
public boolean isChecked() {
return checked;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(checked) {
Bitmap check = BitmapFactory.decodeResource(
getResources(), R.drawable.checkbox_on_background);
int width = check.getWidth();
int height = check.getHeight();
//int margin = 15;
int marginWidth = (int)(canvas.getWidth()/15);
int marginHeight = (int)(canvas.getHeight()/20);
int x = canvas.getWidth() - width - marginWidth;
//int y = canvas.getHeight() - height - margin;
int y = marginHeight;
canvas.drawBitmap(check, canvas.getWidth()-check.getWidth(), 1, new Paint());
}
}
}
I use a Gridview to show all my photos and I want to marked some. I use a BaseAdapter to load the data, here is my method getView ():
public View getView(int position, View convertView, ViewGroup parent) {
MarkableImageView imageView;
if(convertView == null) {
imageView = new MarkableImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams((int)(Preferencias.anchoPantalla/3.5), (int)(Preferencias.altoPantalla/4)));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (MarkableImageView) convertView;
}
if(nivel == -1) {
if(!Preferencias.getIdsImagenesSeleccionadasJuegoMemoria().isEmpty()) {
if(Preferencias.getIdsImagenesSeleccionadasJuegoMemoria().size() > position) {
imageView.setImageResource(
Preferencias.imagenesTodas[Preferencias.getIdsImagenesSeleccionadasJuegoMemoria().get(position)]);
}
}
} else if(nivel == 0) {
if(!listaIdsDescubiertas.isEmpty()) {
if(listaIdsDescubiertas.size() > position) {
imageView.setImageResource(Preferencias.imagenesTodasPequeñas[listaIdsDescubiertas.get(position)]);
}
}
} else {
switch(nivel) {
case 1:
imageView.setImageResource(Preferencias.imagenesNivel1[position]);
break;
case 2:
imageView.setImageResource(Preferencias.imagenesNivel2[position]);
break;
}
if(!listaIdsDescubiertas.isEmpty()) {
for(Integer pos : listaIdsDescubiertas) {
if(calcularPosicion(position, nivel) == pos) {
imageView.setChecked(true);
}
}
}
}
return imageView;
}
Everything works perfectly but the problem is that when I start to move around the screen looks brand in the photos that I want to stop playing but the screen in certain positions marks are removed. Then touch the screen again reappears. How I can fix it to appear forever?
My second question is that I generate a grid where each image is a class called TileJuegoMemoria extending ImageView.
for (int r = 0; r < rows; r++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
row.setGravity(Gravity.CENTER);
for (int c = 0; c < columns; c++) {
TileJuegoMemoria tile = new TileJuegoMemoria(this, tilebackResource,
tilesImagenesRepetidas.get(position), position, sideLength, sideLength);
tile.setClickable(true);
tile.setId(position);
tile.setOnClickListener(tileOnClickListener);
row.addView(tile);
position++;
}
memoryBoardLayout.addView(row);
}
I add each object to a listener to click on it. The Listener has its method onClick () like this:
tileOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
TileJuegoMemoria tempTile = (TileJuegoMemoria) v;
if (tempTile.getVisibility() == TileJuegoMemoria.INVISIBLE || (!tempTile.isBackVisible)) {
return;
}
int move = gameEngine.doMove(tempTile);
if (move == -1) {
return;
}
gameEngine.selectedTile = tempTile;
gameEngine.selectedTile.flipOver();
if (move == 2) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
TileJuegoMemoria precedentMoveselectedTile = gameEngine.movesArray[0];
if (gameEngine.selectedTile.tileFace.equals(precedentMoveselectedTile.tileFace)) {
if(eliminarAcertados) {
gameEngine.selectedTile.hide();
precedentMoveselectedTile.hide();
}
} else {
gameEngine.selectedTile.flipOver();
precedentMoveselectedTile.flipOver();
turnoJugador1 = !turnoJugador1;
}
gameEngine.clearMoveArray();
}
});
}
}, 1000);
}
}
};
}
The game is for 2 players where they take turns playing two screen images that change. My question is how it might do so after Player 1's turn, was the computer who did click on two random images.
Where gender had thought the images saved in a list the coordinates of each image to PerformClick () on it. What I can do? Thanks!

Categories

Resources