ViewCompat.setElevation doesn't draw view over another view below LOLLIPOP? - android

Using the code below, I'm trying to draw a View over another view when one of the views is clicked, and reverse it when clicked again. in API level 25 and it works fine, but on another phone with API 17, it doesn't work
private void elevationTest() {
final View view1 = findViewById(R.id.view1);
final View view2 = findViewById(R.id.view2);
final boolean[] asdf = {true};
view1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (asdf[0]) {
ViewCompat.setElevation(view1, 1);
ViewCompat.setElevation(view2, 2);
asdf[0] = !asdf[0];
} else {
ViewCompat.setElevation(view1, 2);
ViewCompat.setElevation(view2, 1);
asdf[0] = !asdf[0];
}
}
});
}
is there a way to make it happen? Thanks.
EDIT:
I'm not trying to simulate a drop shadow under my Views, just trying to draw them over each other (in this case, when the first view is clicked).

Related

Add & delete item from LinearLayout using ArrayAdapter

I am doing bubble display of selected contacts. Each telephone bubble is a LinearLayout, which contains ImageView and TextView. These bubbles are then displayed in another LinearLayout which is child of HorizontalScrollView.
It child/parent tree looks like this:
- HorizontalScrollView
|- LinearLayout (id="#+id/telField")
|- LinearLayout (id="#+id/telBox") <- is programmatically added to parent
|- TextView (id="#+id/telNumber")
|- ImageView (id="#+id/delNumber")
In my .java class I call this method to display "telBox" LinearLayout in "telField" LinearLayout:
public void createAdapter() {
telList = new ArrayAdapter<>(this, R.layout.text_buble, R.id.telNumber, telNumList);
telField = (LinearLayout) findViewById(R.id.telField);
telField.removeAllViews();
final int adapterCount = telNumList.size();
for (ik = 0; ik < adapterCount; ik++) {
final View item = telList.getView(ik, null, null);
telField.addView(item);
item.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
telField.removeView(item);
telNumList.remove(ik-1);
telList.notifyDataSetChanged();
refresh();
}
});
}
}
Method refresh(); – is custom method which helps to "reload" Activity: it gets App values, refreshes warning ImageViews and cals createAdapter() method.
Big button "SELECT" calls an Intent which returns a selected phone number from a contacts book. I call this code to update my LinearLayout with id "telField":
telNumList.add(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)));
createAdapter();
Problem I face is:
After I click on LinearLayout with id "telNumber" it one by one deletes every bubble (no matter which I clicked) until it reaches first added bubble. It also crashes 50/50 when reaches first added element, I have not figured out a dependency. The error it returns is "out of bounds error", so I think it is connected with ik - 1 line.
My question is: How do I better construct my ArrayAdapter?
In your code you are trying to remove the view by ik which is getting change continuously because of which your coding is removing last view I have modified your code as given below
for (ik = 0; ik < adapterCount; ik++) {
final int position=ik;
final View item = telList.getView(ik, null, null);
telField.addView(item);
item.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
telField.removeView(item);
telNumList.remove(position);
telList.notifyDataSetChanged();
//refresh();
createAdapter();
}
});
}
Here position will help you to remove the particular view which you want to remove. I hope this is what you are asking for.
Inside your for loop, write these line of code:
for (ik = 0; ik < adapterCount; ik++) {
final View item = telList.getView(ik, null, null);
item.setTag(ik);
telField.addView(item);
item.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int index = Integer.parseInt(v.getTag().toString());
telNumList.remove(index);
refresh();
}
});
}
Hope it will help you out.

Changing infoWindow view depending on click listener

I am trying to implement a Google Map marker with infoWindow that if someone clicks on this infoWindow, it plays a song and if clicks again, it stops. To visualize this, I write a custom infoWindow layout. There is, in infoWindow, you can see user and track info with a button. This button shows play icon if the track does not begin to play yet, and if it pressed (press on infoWindow, not the button), I hope it changes its icon from "play" to "stop". However, I cannot change my custom infoWindow's view depending on infoWindowClickListener activity. I tried to change infoWindowAdapter especially but I do not want to change view of all other infoWindows and also I want to see the change immediately. In this way, the infoWindow refreshes its view after I click on the marker again. In other words, it does not change the view simultaneously with my click action.
Here you can see what I am talking about. Stop status on left, play status on right:
Here is my futile effort for adapter:
public class OrangeInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
Context context;
ImageButton playButton;
boolean onPlay;
public OrangeInfoWindowAdapter(Context context, boolean onPlay) {
this.context = context;
this.onPlay = onPlay;
}
#Override
public View getInfoWindow(Marker arg0) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.orange_infowindow, null);
v.setMinimumWidth(280);
v.setMinimumHeight(120);
TextView tvUsername = (TextView) v.findViewById(R.id.tv_username);
TextView tvTrack = (TextView) v.findViewById(R.id.tv_track);
int index = arg0.getTitle().indexOf("*");
try {
tvUsername.setText(arg0.getTitle().substring(0, index - 1) + "\n" + arg0.getTitle().substring(index + 2));
} catch (StringIndexOutOfBoundsException e) {
}
tvUsername.setTextSize(10);
tvUsername.setTextColor(Color.rgb(70, 70, 70));
index = arg0.getSnippet().indexOf("*");
try {
tvTrack.setText(arg0.getSnippet().substring(0, index - 1) + "\n" + arg0.getSnippet().substring(index + 2));
} catch (StringIndexOutOfBoundsException e) {
}
tvTrack.setTextSize(10);
tvTrack.setTextColor(Color.rgb(230, 92, 1));
playButton = (ImageButton) v.findViewById(R.id.playButton);
if (onPlay)
onPlay();
return v;
}
public void onPlay() {
playButton.setBackgroundResource(R.drawable.info_stop_button);
}
public void onStop() {
playButton.setBackgroundResource(R.drawable.info_play_button);
}
#Override
public View getInfoContents(Marker arg0) {
return null;
}
}
And this is my onInfoWindowClick():
#Override
public void onInfoWindowClick(Marker marker) {
if (!infoWindowPlayerActive) {
int index = findMarkerIndex(marker);
OrangeInfoWindowAdapter infoWindowAdapter2 = new OrangeInfoWindowAdapter(getActivity().getApplicationContext(), true);
googleMap.setInfoWindowAdapter(infoWindowAdapter2);
new InfoWindowPlayerTask(mainActivity).execute(activities.get(index).getTrackId());
infoWindowPlayerActive = true;
}
else {
// same thing...
infoWindowPlayerActive = false;
}
}
If you want more information to understand the problem clearly, please ask me.
The GoogleMap API v.2 does not support any interaction on InfoWindow, besides opening and closing it.
However, there is an amazing hack implemented in this answer, on how you should create an interactive View inside your InfoWindow. Keep in mind that the same technique applies for Fragments too.
From the official documentation:
Note: The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (e.g., after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However you can listen to a generic click event on the whole info window as described in the section below.
I found a sloppy but working solution:
#Override
public void onInfoWindowClick(Marker marker) {
if (!infoWindowPlayerActive) {
googleMap.setInfoWindowAdapter(infoWindowAdapterOnPlay);
marker.showInfoWindow();
newClickedInfoWindowIndex = findMarkerIndex(marker);
if (lastClickedInfoWindowIndex != newClickedInfoWindowIndex) {
new InfoWindowPlayerTask(mainActivity).execute(activities.get(newClickedInfoWindowIndex).getTrackId());
}
else {
mainActivity.getPlayerManager().clickPlayPause();
}
lastClickedInfoWindowIndex = newClickedInfoWindowIndex;
infoWindowPlayerActive = true;
}
else {
googleMap.setInfoWindowAdapter(infoWindowAdapter);
marker.showInfoWindow();
mainActivity.getPlayerManager().clickPlayPause();
infoWindowPlayerActive = false;
}
}
public int findMarkerIndex(Marker marker) {
for (int i = 0; i < markers.size(); i++) {
if (marker.getPosition().equals(markers.get(i).getPosition())) {
return i;
}
}
return -1;
}
Of course, assume that infoWindowPlayerActive, lastClickedInfoWindowIndex, newClickedInfoWindowIndex are defined in the class above.

Android dynamically drawing more than 1000 text view is causing full application to not responding

This is my function which will fetch some 1300 record from SQLite database and draw a series of text view inside the table layout. But when this function starts executing full application is not responding for some time. Table layout is again inside a Scroll View.
Basically I want it to load in back ground.so that remaining application is still responsive
public void LoadAlarmNotifications() {
int SerNo = 0 ;
TextView SerNoTxtVw;
TextView AlarmTxtVw;
TextView TimeOccuredTxtVw;
TextView UploadTxtTxtVw;
Notificationtablelayout.setGravity(Gravity.CENTER);
pastEvent_tbleList = oDatabaseHandler.FetchPastEventDetails(sDiagnosisID);
if(pastEvent_tbleList != null)
{
for(Pastevents_tble PEvents_tble: pastEvent_tbleList)
{
final TableRow row = new TableRow(this.getApplicationContext());
nAlarmType = PEvents_tble.GetAlarmID();
nRowID = PEvents_tble.GetEventNo();
SerNo = PEvents_tble.GetEventNo();
SetAlarmType(nAlarmType); // Set Alarm
tAlarmTime = PEvents_tble.GetStrtTime();
sUploadStatus = PEvents_tble.GetUploadStatus();
row.setId(nRowID);
SerNoTxtVw =new TextView(this.getApplicationContext());
AlarmTxtVw =new TextView(this.getApplicationContext());
TimeOccuredTxtVw=new TextView(this.getApplicationContext());
UploadTxtTxtVw =new TextView(this.getApplicationContext());
SerNoTxtVw.setText(Integer.toString(SerNo));
SerNoTxtVw.setWidth(80);
SerNoTxtVw.setHeight(40);
SerNoTxtVw.setGravity(Gravity.CENTER);
SerNoTxtVw.setPadding(2, 2,2,2);
SerNoTxtVw.setTextColor(Color.parseColor("#FFAADDFF"));
row.addView(SerNoTxtVw);
AlarmTxtVw.setText(sAlarmName);
AlarmTxtVw.setWidth(100);
AlarmTxtVw.setHeight(40);
AlarmTxtVw.setGravity(Gravity.LEFT);
AlarmTxtVw.setPadding(2,2,2,2);
// AlarmTxtVw.setBackgroundColor(Color.LTGRAY);
row.addView(AlarmTxtVw);
TimeOccuredTxtVw.setText(tAlarmTime);
TimeOccuredTxtVw.setWidth(140);
TimeOccuredTxtVw.setHeight(40);
TimeOccuredTxtVw.setGravity(Gravity.CENTER);
TimeOccuredTxtVw.setPadding(2,2,2,2);
// TimeOccuredTxtVw.setBackgroundColor(Color.LTGRAY);
row.addView(TimeOccuredTxtVw);
UploadTxtTxtVw.setText(sUploadStatus);
if(sUploadStatus.equals("Y")){
UploadTxtTxtVw.setText("✔");
UploadTxtTxtVw.setTextColor(Color.parseColor("#FF00FF00"));
}
else if(sUploadStatus.equals("N")){
UploadTxtTxtVw.setText("X");
UploadTxtTxtVw.setTextColor(Color.parseColor("#FFFF0000"));
}else
{
UploadTxtTxtVw.setText("✔");
UploadTxtTxtVw.setTextColor(Color.parseColor("#FFAADDFF"));
}
UploadTxtTxtVw.setWidth(100);
UploadTxtTxtVw.setHeight(40);
UploadTxtTxtVw.setGravity(Gravity.CENTER);
UploadTxtTxtVw.setPadding(2,2,2,2);
// UploadTxtTxtVw.setBackgroundColor(Color.LTGRAY);
row.addView(UploadTxtTxtVw);
Notificationtablelayout.addView(row);
nProgressCounter++;
row.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View SelectedRowVw) {
if(!bSwitchPopOpen)
{
}
});
}
LoadingTxtView.setVisibility(View.GONE);
bEpisodeLoad = true;
} else
{
bEpisodeLoad = true;
LoadingTxtView.setText("No Snapshot available...");
}
}
pastEvent_tbleList size is 1335. Any idea how to optimize this. Instead of text view is there any other light control?
You should use the Loader pattern to do this so that you only load content that the user will actually see, and you should also reuse the text views on the screen. This is what ListView / CursorLoader were created to solve, so you really ought to reuse these components if at all possible.
You should use listview, because it loads visible area so application will not stop doing calculations and you can scroll up and down and see your texviews

Clear the previous selected View Background and change the background of newly selected View in Onclick - Android

I want to change the background view when it's pressed (its working). My problem is, If i press the other view (not the same one) in the list, i want to set my background to Black of the newly selected view and change the background to White of the previous selected view. Here is my Implementation
for(final TotalPlayers player : this.playerData){
final ArrayList<View> addedPlayerViews1 = getPlayerView(player);
dropPlayersListView.addView(addedPlayerViews1.get(0));
addedPlayerViews1.get(0).setOnClickListener(new OnClickListener() {
boolean highlight = false;
#Override
public void onClick(View v) {
if (!highlight)
{
addedPlayerViews1.get(0).setBackgroundColor(Color.BLACK);
highlight=true;
}
else {
addedPlayerViews1.get(0).setBackgroundColor(Color.WHITE);
highlight=false;
}
}
});
}
}
addedPlayerViews1.get(1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
addedPlayerViews1.get(0).setBackgroundColor(Color.WHITE);
highlight=false;
}
});
I assumed that you can get the other view by get(1).
The problem of your code was you only handled the onClick event of your view where you want to change the background. but you also need to handle the onClick of other view too.

Android:Animated menu not dissappearing

I am dealing with a view flipper. I have 2 views in my view flipper and in the second view on completing a frame animation an animated popup menu translating from bottom. when I press the back button I could able to flip to first view from second but again when I switch to the second view from first view that popup menu is not disappearing. I used reset() and setfillafter() methods but no result
How to solve this? any Idea?
Here is my code.
final Animation popup = new TranslateAnimation(0, 0, 200, 0);
popup.setDuration(20000);
popup.setFillAfter(true);
hearttap.setOnClickListener(new View.OnClickListener() {
public void onClick(final View view) {
final RelativeLayout popuplayout = (RelativeLayout) findViewById(R.id.popuplayout);
final ImageView ekgimgview4 = (ImageView) findViewById(R.id.ekgimgview4);
ekgimgview4.setVisibility(ImageView.VISIBLE);
ekgimgview4.setBackgroundResource(R.anim.ekgtimer);
AnimationDrawable ekgframeAnimation4 = (AnimationDrawable) ekgimgview4
.getBackground();
if (ekgframeAnimation4.isRunning()) {
findViewById(R.id.ekgimgview4).postDelayed(new Runnable() {
public void run() {
// openOptionsMenu();
popuplayout.startAnimation(popup);
popup.setFillAfter(true);
popup.setStartTime(30000);
ekgimgview4.setVisibility(view.GONE);
}
}, 30000);
final Button ekgbutton = (Button) findViewById(R.id.ekgbutton);
ekgbutton.setOnClickListener(new View.OnClickListener() {
public void onClick( View view) {
RelativeLayout popuplayout = (RelativeLayout) findViewById(R.id.popuplayout);
popuplayout.setVisibility(View.INVISIBLE);
}
});
You need to use the dismiss() function for popups. So use the following code whenever you transition between Views:
popup.dismiss();
I would edit it into your code myself, but the way StackOverflow handles displaying code tags made your code half into HTML code tags and half not.

Categories

Resources