How to add onClick method to ImageView inside a grid layout? - java

I'm creating a tic-tac-toe like game which contains some circular balls that are dropped when user taps on the rooms where he wants to deploy. I have added those images inside a grid layout but I'm not able to run a dedicated method when a user taps on them. I have assigned the method to onclick property of imageview but the java code isn't being executed.
EDIT: I tried to log something when the grid layout was click and it was logged. So the conclusion is that the grid layout is blocking the click to be registered to the imageview.
Here's my Java code:
public void dropIn(View view) {
ImageView counter = (ImageView) view;
counter.setTranslationY(1000f);
counter.setImageResource(R.drawable.yellow);
counter.animate().translationYBy(1000f).setDuration(300);
}
This is the XML code for the image view:
<ImageView
android:id="#+id/imageView5"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_margin="10dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="20dp"
android:onClick="dropIn"
app:layout_column="1"
app:layout_row="1" />
Here is the XML code for the grid:
<android.support.v7.widget.GridLayout
android:layout_width="match_parent"
android:layout_height="360dp"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="185dp"
android:layout_marginEnd="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="186dp"
android:background="#drawable/board"
app:columnCount="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:rowCount="3">

You can try to do it programmatically instead of assigning the method via XML view.
In first place you need to create a new ImageView and then get the view rendered with findViewById() method. Then, assign the onClickListener with the "dropIn" logic:
ImageView counter = findViewById(R.id.imageView5);
counter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter.setTranslationY(1000f);
counter.setImageResource(R.drawable.yellow);
counter.animate().translationYBy(1000f).setDuration(300);
}
});

Related

Nested RecyclerView load second item with lag

I'm trying to make Recyclerview like Shareit app. It uses sticky header and something like Cardview. I searched and found somethings for implementing sticky header with itemdecoration and it's okay. But for Cardview part, I tried to make nested Recyclerview but performance was so bad, Because using two vertical Recyclerview is not good at all. Is there any better way to achieve this?
The problem with performance is for when i scroll down. It makes lag on creating second item in parent Recyclerview.
AppheaderAdapter:
#Override
public AppHeaderAdapter.HeaderHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_media_header, parent, false);
HeaderHolder headerHolder = new HeaderHolder(view);
return headerHolder;
}
class HeaderHolder extends RecyclerView.ViewHolder { //story
final ImageView arrow;
final TextView tarikh;
final TextView tedad;
final CheckBox tick;
final RecyclerView item_recyc;
HeaderHolder(View itemView) {
super(itemView);
arrow = itemView.findViewById(R.id.header_arrow);
tarikh = itemView.findViewById(R.id.header_tarikh);
tedad = itemView.findViewById(R.id.header_tedad);
tick = itemView.findViewById(R.id.header_tick);
item_recyc = itemView.findViewById(R.id.header_recyc);
}
}
#Override
public void onBindViewHolder(#NonNull AppHeaderAdapter.HeaderHolder headerHolder, int position) {
final AppHeader appHeader = appHeaders.get(position);
...
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, span);
gridLayoutManager.setRecycleChildrenOnDetach(true);
headerHolder.item_recyc.setLayoutManager(gridLayoutManager);
headerHolder.item_recyc.setNestedScrollingEnabled(false);
AppItemAdapter adapter = new AppItemAdapter(context, appHeader.getAppList(), fr_parent, width);
headerHolder.item_recyc.swapAdapter(adapter, true);
...
}
item_media_header.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/header_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/so_round_so_white"
app:cardCornerRadius="10dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/header_arrow"
android:layout_width="30dp"
android:layout_height="30dp"
android:padding="8dp"
android:src="#drawable/header_arrow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/header_tarikh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/fragment_file"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/header_arrow"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/header_tedad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:textColor="#AAAAAA"
android:textSize="#dimen/fragment_file"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/header_tarikh"
app:layout_constraintTop_toTopOf="parent" />
<CheckBox
android:id="#+id/header_tick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:button="#null"
android:clickable="false"
android:drawableRight="#drawable/file_checkbox"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/header_recyc"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.cardview.widget.CardView>
EDIT 1:
I find that just first Cardview is loaded and second one is not loaded until I scroll to end of first one and then load second CardView item and it lags because of second RecyclerView.
I found that Shareit use previous created adapter and just change its internal datalist, So i do that, but still has lag on second item.
Edite 2:
I use one time created adapter on all RecyclerView but still has lag.
Edit 3:
It's a known bug that innerRecyclerView load all items at first and that cause my lag too. because inner Recyclerview is inside NestedScrollView (RV) and it loads all content.Using constant height doesn't work, But I'll update question if I find something better.
You can achieve this with ConstraintLayout and Flow.
EDIT: Sorry, I just realised I wrote everything in Kotlin. If you cannot understand something I can try to translate it to Java.
xml:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout"
...>
<androidx.constraintlayout.helper.widget.Flow
android:id="#+id/flow"
app:flow_wrapMode="aligned"
app:flow_horizontalStyle="spread_inside"
app:flow_maxElementsWrap="4"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Adding of items:
val constraintLayout = itemView.findViewById(R.id.constraintLayout)
val flow = itemView.findViewById(R.id.flow)
val items // items given to the viewHolder to display
val layoutInflater = LayoutInflater.from(context)
items.forEach { item ->
val view = // create item view, e.g. DataBinding, ...
view.id = ViewCompat.generateViewId()
constraintLayout.addView(root)
flow.addView(root)
}
}
// if there are less than 4 items you have to add invisible dummy items. Otherwise, the alignment will look different for these ViewHolders
if(items.size>=4) return
for (i in 0..(4-items.size)) {
val view = // create dummy view
view.id = ViewCompat.generateViewId()
constraintLayout.addView(root)
flow.addView(root)
}
So far, Using vertical RV inside vertical RV has bug. Because of inner RV make long height and outer RV has no idea of this, So it create just first Item, but all items in inner RV. using all solution on Stack O.F. had no effect!

Translate Animation Not Working with OnClickListener

I am using the following translate animation to bring an imageView onto the screen in the onCreate method of my activity :
mScanner = (ImageView)findViewById(R.id.logo_img);
Display display = getWindowManager().getDefaultDisplay();
final int height = display.getHeight();
mAnimation = new TranslateAnimation(0, 0, -300, height * 2/10);
mAnimation.setDuration(2500);
mAnimation.setFillAfter(true);
mScanner.setAnimation(mAnimation);
mScanner.setVisibility(View.VISIBLE);
This works fine. Now I have two buttons at the bottom of my screen inside of a linear layout, like this :
<LinearLayout
android:orientation="vertical"
android:layout_gravity="bottom"
android:layout_height="0px"
android:layout_weight="25"
android:weightSum="100"
android:layout_width="fill_parent">
<Button
android:layout_height="0px"
android:layout_weight="50"
android:id="#+id/log_in_btn"
android:background="#drawable/btn_back"
android:text="LOG IN"
android:onClick="logIn"
android:textSize="25dp"
android:textColor="#FFFFFF"
android:layout_width="fill_parent">
</Button>
<Button
android:layout_height="0px"
android:layout_weight="50"
android:textColor="#FFFFFF"
android:background="#drawable/btn_back"
android:textSize="25dp"
android:text="SIGN UP"
android:layout_width="fill_parent">
</Button>
</LinearLayout>
I added the following onClickListener to the first button. My intention is to move the whole linear layout up the screen to the height where the logo previously was (20% of screen height). However, when I press the button nothing happens.
Button button = (Button) findViewById(R.id.log_in_btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LinearLayout login = (LinearLayout) view.getParent();
login_anim = new TranslateAnimation(0,0,0, height* 2/10);
login_anim.setDuration(2500);
login_anim.setFillAfter(true);
login.setAnimation(login_anim);
login_anim.start();
}
});
Your problem is that you aren't actually calling the animation on the LinearLayout. Notice you never attach the animation to the view itself. Instead of login_anim.start() try calling login.startAnimation(login_anim) instead.

How to use Onchanged and OnTouch for the same boutton in Android

I'm working on an Android application at my work and I am having a problem.
I need to know how I can use the Onchanged and OnTouch methods for the same button with conditions?
For example: If my button is on left than you can only touch it to do something and if it is on right than you can use it as a spinner.
I will suggest to use an image Button for both the case. As your requirement, use image Button as a normal Button when in left-side and spinner when on right. You can make use of a variable "i" to be set if it is in right side. Change the method if it is reset.
<ImageButton
android:id="#+id/imageButtonSpinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
/>
Then define your spinner in terms of what you need inside it. Like this may be....
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinnerLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageButton
android:id="#+id/love"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="#+id/hem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="#+id/love"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
In the mainActivity
protected void onCreate(Bundle savedInstanceState) {
...
addListenerToSpinnerButton();
}
private void addListenerToSpinnerButton(){
spinnerButton = (ImageButton) findViewById(R.id.imageButtonSpinner);
spinnerButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if(p != null)
showSpinner(MainActivity.this, p);
}
});
}

Can't make progress bar visible after button click

I want to show simple round progress bar after I clicked on a button, but it's doesn't work. Look on my XML
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/progress_layout">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:layout_gravity="center"
android:visibility="invisible" />
</FrameLayout>
And my java code
postPet = (Button) myFragmentView.findViewById(R.id.post_pet);
postPet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressBar.setVisibility(View.VISIBLE);
}
});
There is no error, nothing happening after click.
P.S. I initialize variable progressBar in fragment's onCreate method
LayoutInflater infl = getActivity().getLayoutInflater();
ViewGroup rootGroup = (ViewGroup) getActivity().findViewById(R.id.progress_layout);
View root = infl.inflate(R.layout.fragment_new_pet_form, rootGroup);
progressBar = (ProgressBar) root.findViewById(R.id.progressBar);
You should add your pb over a button in xml like:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/progress_layout">
<Button
android:id="#+id/post_pet"
your button description here />
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
this way it has to work and you would not need to inflate the pb additionally.
Try adding one of the associated styles: http://developer.android.com/reference/android/widget/ProgressBar.html
You can also set the background color of its parent to some value, and see if any part is opaque: if not, the progress bar has no width and height or is not visible.
Finally you can use hierarchyviewer with the emulator to inspect the layout and verify what's happening.
Also if the frame layout has no other children, get rid of it and use layout_gravity to position the progress bar in its parent: no need for the extra viewgroup!

How do I use a custom icon at a PinItButton of their SDK?

I want to use a custom icon for my pinIt button. I keep getting the old layout overwritten when I run my app while in the preview the icon that I prefer is shown.
<com.pinterest.pinit.PinItButton
android:id="#+id/car_info_comment_pintrest"
android:layout_width="#dimen/car_info_button_width"
android:layout_height="wrap_content"
android:background="#drawable/ic_comment_pintrest"
android:drawableTop="#drawable/ic_comment_pintrest"
android:text="100"
android:textColor="#fff" />
I've fixed it with a hacky solution. I've added another button and called the OnClickEvent of the PinIt button and made that buttons visibility: gone.
holder.mPinterestButton = ((PinItButton) holder.content.findViewById(R.id.pin_it));
holder.mPinterestButton.setImageUrl("http://placekitten.com/400/300");
holder.mPinterestButton.setUrl("http://placekitten.com"); // optional
holder.mPinterestButton.setDescription("A place kitten!"); // optional
holder.pinterestButton = ((Button) holder.content.findViewById(R.id.car_info_comment_pinterest));
holder.pinterestButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.mPinterestButton.performClick();
}
});
XML:
<Button
android:id="#+id/car_info_comment_pinterest"
android:layout_width="#dimen/car_info_button_width"
android:layout_height="wrap_content"
android:drawableTop="#drawable/ic_comment_pinterest"
android:background="#null"
android:text="100"
android:textColor="#fff" />
<com.pinterest.pinit.PinItButton
android:id="#+id/pin_it"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
/>

Categories