OnClickListener not working for first item in GridView inside ViewPager - android-layout

Inside ViewPager, there is a gridview which has a grid of single choice answers with textviews and images. When i clicked on any answer, the textview should change its color to RED else WHITE. Its working fine for all the other answers except the first one. When i first clicked on first answer in gridview, it doesn't change the color, on second click it turns to RED, but then when i change the option, the RED color doesn't change to WHITE for first option. Look at the screen below,
Sorry Screen submission is not allowed for me as i am a new user...
Inside GridFragment#OnActivityCreated():
gridview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long arg3) {
currentPage = new TestTopics().getCuttentPage();
tv = ((ViewHolder) v.getTag()).lbl;
if(selectedValues.containsKey(currentPage))
{
selectedValues.get(currentPage).setTextColor(Color.WHITE);
selectedValues.remove(currentPage);
selectedValues.put(currentPage, tv);
selectedValues.get(currentPage).setTextColor(Color.RED);
}
else
{
selectedValues.put(currentPage, tv);
selectedValues.get(currentPage).setTextColor(Color.RED);
}
}
});
ImageAdapter#getView() method:
public View getView(int position, View convertView, ViewGroup parent) {
numTopics = mTopicList.getNumTopics ();
ViewHolder holder;
holder = new ViewHolder();
if (convertView == null) {
int layoutId = R.layout.demo_pager_grid_item;
LayoutInflater li = ((Activity) mContext).getLayoutInflater();
childView = li.inflate (layoutId, null);
holder.img = (ImageView) childView.findViewById(R.id.image);
holder.lbl = (TextView) childView.findViewById(R.id.title);
childView.setTag(holder);
} else {
childView = convertView;
holder = (ViewHolder) childView.getTag();
}
if (childView != null) {
// Set the width and height of the child view.
childView.setLayoutParams(new GridView.LayoutParams(mCellWidth, mCellHeight));
int j = position + mImageOffset;
if (j < 0) j = 0;
if (j >= numTopics) j = numTopics - 1;
imageView = (ImageView) childView.findViewById (R.id.image);
if (imageView != null) {
Resources res = mContext.getResources ();
int imagePadding = res.getDimensionPixelSize (R.dimen.grid_image_padding);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setBackgroundResource (R.color.background_grid1_cell);
imageView.setPadding (imagePadding, imagePadding, imagePadding, imagePadding);
imageView.setImageBitmap (mTopicList.getTopicImage (j));
imageView.setTag (new Integer (j));
}
textView = (TextView) childView.findViewById (R.id.title);
if (textView != null)
{
textView.setText(mTopicList.getTopicTitle (j));
textView.setTag (mTopicList.getTopicTitle (j));
holder.lbl.setTag(mTopicList.getTopicTitle (j));
}
}
return childView;
}
I have seen this link : OnClickListener not working for first item in GridView, and follow the answer, but didn't get succeed on it...
Where I'm going wrong?

Answered in a question edit. Converted to a community wiki answer. See What is the appropriate action when the answer to a question is added to the question itself? )
The OP wrote:
have solved it....
I added gridview.setBackgroundColor(Color.TRANSPARENT); in my following code :
if(patternItems.containsKey(currentPage) && selectedValues.containsKey(currentPage))
{
selectedValues.get(currentPage).setTextColor(Color.WHITE);
selectedValues.remove(currentPage);
selectedValues.put(currentPage, tv);
selectedValues.get(currentPage).setTextColor(Color.RED);
**gridview.setBackgroundColor(Color.TRANSPARENT);**
patternItems.remove(currentPage);
patternItems.put(currentPage,tv.getText().toString());
}
else
{
selectedValues.put(currentPage, tv);
selectedValues.get(currentPage).setTextColor(Color.RED);
**gridview.setBackgroundColor(Color.TRANSPARENT);**
patternItems.put(currentPage,tv.getText().toString());
}

Related

focusSearch(View.FOCUS_RIGHT) in vertical LinearLayout

I have 2 EditTexts and 1 TextView in an xml file in a vertical LinearLayout, with hight 0dp and weight 1, TextView onClick fires the below code.
I need the focus to move to the "next" EditText, but when the last EditText has the focus, the viewToRight points to the EditText above it when it suppose to be null. the problem goes away if I remove hight 0 and weight 1
and give hight of wrap_content.
How can I get viewToRight to have the correct value with my current xml.
The code below gets used with other view arrangements and I expected focusSearch(View.FOCUS_RIGHT) to "know" when there is no view to the right in a vertical linearLayout.
View viewCurrent = getCurrentFocus();
View viewToRight = viewCurrent.focusSearch(View.FOCUS_RIGHT);
View viewToDown = viewCurrent.focusSearch(View.FOCUS_DOWN);
if (viewToRight != null && viewToRight instanceof EditText) {
viewToRight.requestFocus();
} else if (viewToDown != null && viewToDown instanceof EditText) {
viewToDown.requestFocus();
}
I had to write a code which checks for the parent viewGroup and decide which direction to get its next view to check.
#Nullable
public View getForwardEditText(View currentView) {
View viewNext = null;
assert currentView != null;
View parent = (View) currentView.getParent();
if (parent instanceof LinearLayout) {
int i = ((LinearLayout) parent).getOrientation();
if (i == 1) { //vertical
viewNext = currentView.focusSearch(View.FOCUS_DOWN);
} else { //must be horizontal
viewNext = currentView.focusSearch(View.FOCUS_RIGHT);
}
} else if (parent instanceof RelativeLayout) {
if (currentView.focusSearch(View.FOCUS_DOWN) != null) {
viewNext = currentView.focusSearch(View.FOCUS_DOWN);
} else if (currentView.focusSearch(View.FOCUS_RIGHT) != null) {
viewNext = currentView.focusSearch(View.FOCUS_RIGHT);
}
}
if (viewNext instanceof EditText) {
return viewNext;
} else {
return null;
}
}

Drag and drop JLabel while preserving the original JLabel

I am working on a GUI that displays an image of a floor plan (JLabel with ImageIcon) and a number of small icons (JLabels with ImageIcon) down the left hand side. The idea is to be able to select one of the icons and drag and drop it onto a position on the floor plan. My code is working fine except that when you drag an icon onto the floor plan, I need the original icon to remain in place, so it can be placed in several other positions on the floor plan if required. So I need to be able to clone the icon that I am moving when the mouse is pressed.
My code below shows a temp fix between the //******** markers but of course this only works correctly for the topmost icon. I need to somehow clone "Component comp" as a new JLabel.
Below is the relevant part of my code:
class MouseHandler extends MouseAdapter {
private Component dragComponent;
private Sidebar board;
private Point dragOffset;
public MouseHandler(Sidebar board) {
this.board = board;
}
public Sidebar getBoard() {
return board;
}
#Override
public void mousePressed(MouseEvent e) {
Component comp = getBoard().getComponentAt(e.getPoint());
if (comp != null) {
if (comp instanceof JLabel) {
//**************
String imagePath = "/Downlight 1.gif";
Image Images = new ImageIcon(this.getClass().getResource(imagePath)).getImage();
String path = "Images" + imagePath;
ImageIcon icon = new ImageIcon(path);
JLabel lbl = new JLabel(icon);
lbl.setBounds(22, 26, 36, 36);
lbl.setIcon(new ImageIcon(Images));
lbl.setOpaque(true);
Sidebar board = getBoard();
board.add(lbl, new Point(40, 44));
board.setComponentZOrder(lbl, 0);
//**************
dragComponent = comp;
dragOffset = new Point();
dragOffset.x = e.getPoint().x - comp.getX();
dragOffset.y = e.getPoint().y - comp.getY();
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (dragComponent != null) {
board = getBoard();
Point dragPoint = new Point();
dragPoint.x = e.getPoint().x - dragOffset.x;
dragPoint.y = e.getPoint().y - dragOffset.y;
dragComponent.setLocation(dragPoint);
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (dragComponent != null) {
dragComponent = null;
}
}
}
}
Thanks in advance for any help with this.
I found a solution that enabled me to copy the icon and bounds of the original JLabel to a new JLabel, which replaces the one being dragged:
#Override
public void mousePressed(MouseEvent e) {
Component comp = getBoard().getComponentAt(e.getPoint());
if (comp != null) {
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
ImageIcon icon = ((ImageIcon)label.getIcon());
Rectangle rect = label.getBounds();
JLabel lbl = new JLabel(icon);
lbl.setBounds(rect);
lbl.setVisible(true);;
lbl.setOpaque(true);
Mainpanel board = getBoard();
board.add(lbl);
board.setComponentZOrder(lbl, 0);
dragComponent = comp;
dragOffset = new Point();
dragOffset.x = e.getPoint().x - comp.getX();
dragOffset.y = e.getPoint().y - comp.getY();
}
}
}

Moving an ImageView located in a WindowManager doesn't work properly

I'm trying to draw an Icon over everything on the screen (TOP MOST) similar to the chathead of new Facebook messenger
I have create a service to work in the background and based on a specific condition my icon should appear on the screen (exactly like when someone sends you a message on facebook the messenger service will hook the message and shows the chathead on the screen to notify you about the new message)
What I did:
I have created the service and gave it the permission to show system alert windows (since the head is actually a system alert window)
[assembly: UsesPermission(Name = Android.Manifest.Permission.SystemAlertWindow)]
I have inherited a class (StickyHeadView) from ImageView and implemented OnTouchListener listener using the following way :
class StickyHeadView : ImageView, Android.Views.View.IOnTouchListener
{
private StickyHeadService OwnerService;
public StickyHeadView(StickyHeadService ContextService, Context context)
: base(context)
{
OwnerService = ContextService;
SetOnTouchListener(this);
}
float TouchMoveX;
float TouchMoveY;
public bool OnTouch(View v, MotionEvent e)
{
var windowService = OwnerService.GetSystemService(Android.Content.Context.WindowService);
var windowManager = windowService.JavaCast<Android.Views.IWindowManager>();
switch (e.Action & e.ActionMasked)
{
case MotionEventActions.Move:
TouchMoveX = (int)e.GetX();
TouchMoveY = (int)e.GetY();
OwnerService.LOParams.X = (int)(TouchMoveX);
OwnerService.LOParams.Y = (int)(TouchMoveY);
windowManager.UpdateViewLayout(this, OwnerService.LOParams);
Log.Debug("Point : ", "X: " + Convert.ToString(OwnerService.LOParams.X) + " Y: " + Convert.ToString(OwnerService.LOParams.Y));
return true;
case MotionEventActions.Down:
return true;
case MotionEventActions.Up:
return true;
}
return false;
}
}
The service has wiindow manager to show the Icon on it...in Service "OnStart" event I initialize the Head :
private StickyHeadView MyHead;
public Android.Views.WindowManagerLayoutParams LOParams;
public override void OnStart(Android.Content.Intent intent, int startId)
{
base.OnStart(intent, startId);
var windowService = this.GetSystemService(Android.Content.Context.WindowService);
var windowManager = windowService.JavaCast<Android.Views.IWindowManager>();
MyHead = new StickyHeadView(this, this);
MyHead.SetImageResource(Resource.Drawable.Icon);
LOParams = new Android.Views.WindowManagerLayoutParams(Android.Views.WindowManagerLayoutParams.WrapContent,
Android.Views.WindowManagerLayoutParams.WrapContent,
Android.Views.WindowManagerTypes.Phone,
Android.Views.WindowManagerFlags.NotFocusable,
Android.Graphics.Format.Translucent);
LOParams.Gravity = GravityFlags.Top | GravityFlags.Left;
LOParams.X = 10;
LOParams.Y = 10;
windowManager.AddView(MyHead, LOParams);
}
as you can see I have declared a WindowManager and added the view (MyHead) to it with special parameters
My Problem :
When ever I try to move the View (My head) it doesn't move in a stable way and keeps having a quake!
I'm testing it using android 4.0.4 on real HTC Phone
I'm using monodroid
Please help...if the implementation of the touch is not right please suggest a better way...thank you.
In your code just use...
TYPE_SYSTEM_ALERT
or
TYPE_PHONE
instead of
TYPE_SYSTEM_OVERLAY
Hope this will help you.
a working example:
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.ic_launcher);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, //TYPE_PHONE
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
windowManager.addView(chatHead, params);
chatHead.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;
}
return false;
}
});
}
The e.GetX()/eGetY() you are using is relative to view position so when you move the view with UpdateViewLayout the next values will be relative to the move. It works using GetRawX()/GetRawY(), but you have to keep track of the initial Down rawX and rawY also.
Here is my JAVA that works:
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
layoutParams.x = Math.round(event.getRawX() - downX);
layoutParams.y = Math.round(event.getRawY() - downY);
windowManager.updateViewLayout(floatingView, layoutParams);
return true;
case MotionEvent.ACTION_DOWN:
downX = event.getRawX() - layoutParams.x;
downY = event.getRawY() - layoutParams.y;
return true;
case MotionEvent.ACTION_UP:
return true;
}
return false;
}
One comment, there's a big downside in using windowManager.updateViewLayout(...) this method will call onLayout on the floating view for each move, and that might be a performance issue, anyway until now I haven't found another method to move the floating view.
Try this might be help ful
first add global variable on your activity:
WindowManager wm;
LinearLayout lay;
float downX,downY;
after put in code to oncreate on your activity
Button btnstart=(Button)findViewById(R.id.button1);
Button btnstop=(Button)findViewById(R.id.button2);
btnstart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(lay==null)
{
wm = (WindowManager) getApplicationContext().getSystemService(
Context.WINDOW_SERVICE);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
| WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.x = (int) wm.getDefaultDisplay().getWidth();
params.y = 0;
// params.height = wm.getDefaultDisplay().getHeight()/2;
params.width = LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.TRANSLUCENT;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.setTitle("Info");
lay = null;
lay = new LinearLayout(getApplicationContext());
lay.setOrientation(LinearLayout.VERTICAL);
// lay.setAlpha(0.5f);
TextView txt_no = new TextView(getApplicationContext());
txt_no.setTextSize(10.0f);
txt_no.setText("Moving view by stack user!");
txt_no.setTextColor(Color.BLACK);
// txt_no.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
// LayoutParams.WRAP_CONTENT));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 0, 0); // margins as you wish
txt_no.setGravity(Gravity.RIGHT);
txt_no.setBackgroundColor(Color.WHITE);
txt_no.setLayoutParams(layoutParams);
txt_no.setPadding(10, 10, 10, 10);
lay.addView(txt_no);
AlphaAnimation alpha = new AlphaAnimation(0.5F, 0.5F);
alpha.setDuration(0); // Make animation instant
alpha.setFillAfter(true); // Tell it to persist after the animation ends
// And then on your layout
wm.addView(lay, params);
txt_no.startAnimation(alpha);
downX=params.x;
downY=params.y;
Log.v("MSES>", "x="+ downX +",y="+ downY);
lay.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
params.x = Math.round(event.getRawX() - downX);
params.y = Math.round(event.getRawY() - downY);
wm.updateViewLayout(lay, params);
Log.v("MSES EVENT>", "x="+ event.getRawX() +",y="+ event.getRawY());
Log.v("MSES MOVE>", "x="+ params.x +",y="+ params.y);
return true;
case MotionEvent.ACTION_DOWN:
downX = event.getRawX() - params.x;
downY = event.getRawY() - params.y;
Log.v("MSES DOWN>", "x="+ params.x +",y="+ params.y);
return true;
case MotionEvent.ACTION_UP:
//params.x = Math.round(event.getRawX() - downX);
//params.y = Math.round(event.getRawY() - downY);
//wm.updateViewLayout(lay, params);
return true;
}
return false;
}
});
}
}
});
btnstop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (lay != null) {
lay.removeAllViews();
wm.removeViewImmediate(lay);
lay = null;
}
}
});

Binding TextArea height to its content

JavaFX: Is it possible to bind TextArea height (row count) to the height of its content?
I would like to dynamically change height of TextArea while writing the text.
Have a look at JavaFX utility class. Although this is not a solution using binding, computeTextHeight(Font font, String text, double wrappingWidth) method can help you.
This is an exact, simple & working solution:
SimpleIntegerProperty count = new SimpleIntegerProperty(20);
int rowHeight = 10;
txtArea.prefHeightProperty().bindBidirectional(count);
txtArea.minHeightProperty().bindBidirectional(count);
txtArea.scrollTopProperty().addListener(new ChangeListener<Number>(){
#Override
public void changed(ObservableValue<? extends Number> ov, Number oldVal, Number newVal) {
if(newVal.intValue() > rowHeight){
count.setValue(count.get() + newVal.intValue());
}
}
});
Alternatively you can use lambdas to simply the syntax even further:
SimpleIntegerProperty count=new SimpleIntegerProperty(20);
int rowHeight = 10;
textArea.prefHeightProperty().bindBidirectional(count);
textArea.minHeightProperty().bindBidirectional(count);
textArea.scrollTopProperty().addListener((ov, oldVal, newVal) -> {
if(newVal.intValue() > rowHeight){
count.setValue(count.get() + newVal.intValue());
}
});
A solution that workq fine in javafx8 (hiding toolbar is inspired from JavaFX TextArea Hiding Scroll Bars):
class MyTextArea extends TextArea {
#Override
protected void layoutChildren() {
super.layoutChildren();
ScrollBar scrollBarv = (ScrollBar) this.lookup(".scroll-bar:vertical");
if (scrollBarv != null) {
System.out.println("hiding vbar");
((ScrollPane) scrollBarv.getParent()).setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
}
ScrollBar scrollBarh = (ScrollBar) this.lookup(".scroll-bar:horizontal");
if (scrollBarh != null) {
System.out.println("hiding hbar");
((ScrollPane) scrollBarh.getParent()).setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
}
}
#Override
protected double computePrefWidth(double width) {
Bounds bounds = getTextBounds();
Insets insets = getInsets();
double w = Math.ceil(bounds.getWidth() + insets.getLeft() + insets.getRight());
return w;
}
#Override
protected double computePrefHeight(double height) {
Bounds bounds = getTextBounds();
Insets insets = getInsets();
double h = Math.ceil(bounds.getHeight() + insets.getLeft() + insets.getRight());
return h;
}
//from https://stackoverflow.com/questions/15593287/binding-textarea-height-to-its-content/19717901#19717901
public Bounds getTextBounds() {
//String text = (textArea.getText().equals("")) ? textArea.getPromptText() : textArea.getText();
String text = "";
text = this.getParagraphs().stream().map((p) -> p + "W\n").reduce(text, String::concat);
text += "W";
helper.setText(text);
helper.setFont(this.getFont());
// Note that the wrapping width needs to be set to zero before
// getting the text's real preferred width.
helper.setWrappingWidth(0);
return helper.getLayoutBounds();
}
}

I need to implement a linerlayout in android and populate with a list of items. I am doing so because i want the list to be non scrollable?

final LinearLayout l = (LinearLayout) findViewById(R.id.linearlist);
public void onTextChanged(CharSequence s, int start, int before,
int count) {
textlength = et.getText().length();
array_sort.clear();
for (i = 0; i < namelist.length; i++) {
if (textlength <= namelist[i].length()) {
if (et.getText()
.toString()
.equalsIgnoreCase(
(String) namelist[i].subSequence(0,
textlength))) {
array_sort.add(namelist[i]);
if (et.getText().length() == 0) {
// array_sort.remove(namelist[i]);
array_sort.clear();
Just instantiate new TextView on the fly and add them to your layout.
TextView view = new TextView(context);
l.addView(view);

Resources