This function is my function
private void previewCapturedImage(){
Log.d("ChildCount", "content child count before:" + mSelectedImagesContainer.getChildCount());
mSelectedImagesContainer.removeAllViews();
Log.d("ChildCount", "content child count after:" + mSelectedImagesContainer.getChildCount());
Iterator<Uri> iterator = mMedia.iterator();
ImageInternalFetcher imageFetcher = new ImageInternalFetcher(this, 500);
while (iterator.hasNext()) {
Uri uri = iterator.next();
// showImage(uri);
Log.i(TAG, " uri: " + uri);
if (mMedia.size() >= 1) {
mSelectedImagesContainer.setVisibility(View.VISIBLE);
}
View imageHolder = LayoutInflater.from(this).inflate(R.layout.media_layout, null);
// View removeBtn = imageHolder.findViewById(R.id.remove_media);
// initRemoveBtn(removeBtn, imageHolder, uri);
ImageView thumbnail = (ImageView) imageHolder.findViewById(R.id.media_image);
if (!uri.toString().contains("content://")) {
// probably a relative uri
uri = Uri.fromFile(new File(uri.toString()));
}
imageFetcher.loadImage(uri, thumbnail);
mSelectedImagesContainer.addView(imageHolder);
// set the dimension to correctly
// show the image thumbnail.
int wdpx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, getResources().getDisplayMetrics());
int htpx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
thumbnail.setLayoutParams(new FrameLayout.LayoutParams(wdpx, htpx));
}
}
In the second line mSelectedImagesContainer.removeAllViews(), I am trying to clear the view of all existing children views. but it is not working as expected.
So basically this parent container mSelectedImagesContainer has a horizonal list of images that was passed from one more activity.
Also the output of the logging is accurate, it clears all the childviews but for some reason main activity still shows the old images that were previously selected in the viewgroup.
If anything else is needed please let me know. I have not posted the full code since it's quite large. Anyways, if needed I can post it here with the XML's.
Just an info, I am working on a poly-clicker library, for the image picker and a custom scroll view for images.
Screenshots
1) Here I selected 2 images
2) And these images displayed perfectly in the scroll view
3) Now i selected a different set of images i.stack.imgur.com/sw5hz.jpg
4) However, the first selection is still not cleared from the view i.stack.imgur.com/lKovI.jpg
Answer posted in comments by #Shaishav, where the iterator was passed with a hashset which needed to be cleared, so reinitializing the variable "mMedia" did the job.
Related
I am getting some Images from the API and i don't know the number and now i want to test the UI in Android through Appium and i want to scroll down to the Last image. How can I do this and also I don't know the what the title from the API is coming so that I can ScrollTo("Title") and also i am not able to swipe to the last. Is there anyway?
There is no way to know for sure whether you've scrolled to the last using appium because there is no UI reporting for the edges of a scrollview.
One way to know that you've reached the end of a scroll view without relying on devs is to compare the list of all children of the scrollview every time you swipe. If all children are exactly the same, you've reached the end. An example xpath for this would look like //android.widget.View[#content-desc="Your scrollview]//*, which would grab all children and descendants. Once you have a list to compare, check the content of all children nodes. This will only work if there's something unique in these items. If all items are completely general, there will be nothing to compare and this won't be reliable. Ask devs to add content descriptions or accessibility data to the items if possible.
Another option would be to have the devs embed a uniquely id'd invisible view at the top and bottom of the scrollview. That way, if it can be found by the driver, you know that you've reached the very edge of the view. If there are already unique elements at the edges of your scrollview, you can use those.
In the end, the devs of the application can really help out the process of scrolling, but hopefully the trick of comparing the current scrollview's children can help you.
You can use the screen dimensions to scroll down:
public void scrollDown() {
Dimension size = driver.manage().window().getSize();
int x = size.getWidth() / 2;
int starty = (int) (size.getHeight() * 0.60);
int endy = (int) (size.getHeight() * 0.10);
driver.swipe(x, starty, x, endy, 2000);
}
You can store all the images into a list using its available locator. Then use driver.scrollToExact(list.get(list.size()).getAttribute("name"));
Example:
List<mobileElement> images = driver.findElementsByClass("<locator>");
driver.scrollToExact(images.get(images.size()).getAttribute("name"));
or
driver.scrollToExact(images.get(images.size()).getText());
#Test
public void testScroll()throws Exception
{
for(int i=0;i<4;i++)
{
Thread.sleep(2000);
if (driver.findElement(By.name("end_item")).isDisplayed())
{
driver.findElement(By.name("end_item")).click();
break;
}
else
{
horizontalScroll();
}
}
}
public void verticalScroll()
{
size=driver.manage().window().getSize();
int y_start=(int)(size.height*0.60);
int y_end=(int)(size.height*0.30);
int x=size.width/2;
driver.swipe(x,y_start,x,y_end,4000);
}
The above example works with vertical scroll and it is based on the example given at this blog for horizontal scroll
http://qaautomated.blogspot.in/2016/02/how-to-do-horizontal-scroll-in-appium.html
I hope this works for you.
To do this you must know resource id or cont-desc of scrollable element. You also need to know className of your scrollable element.
If you have cont-desc in scrollable list
try {
String scrollableList="your con-desc of scrollable List";
String elementClassName="android.something.something";
String anyText="any text";
driver.findElement(MobileBy.AndroidUIAutomator(
"new UiScrollable(new UiSelector().description(\"" + scrollableList + "\")).getChildByText("
+ "new UiSelector().className(\"" + elementClassName + "\"), \"" + anytext + "\")"));
}catch (Exception e){
System.out.println("Cannot scroll further");
}
If you have resource-id in scrollable list
try {
String scrollableList="your con-desc of scrollable List";
String elementClassName="android.something.something";
String anyText="any text";
driver.findElement(MobileBy.AndroidUIAutomator(
"new UiScrollable(new UiSelector().resourceId(\"" + scrollableList + "\")).getChildByText("
+ "new UiSelector().className(\"" + elementClassName + "\"), \"" + anytext + "\")"));
}catch (Exception e){
System.out.println("Cannot scroll further");
}
If the screen cannot be scroll further it will throw error which will be catched by catch block.
I am working on a project that will display math problems to the screen such as:
10 + 5 =
and then the user will need to guess the answer. I am doing this as more of way for me to learn how android ticks.
I have images from 0 to 9 saved in the drawable folder for each of the dpi setting I need to account. I also have the operators (+,-,*,/,=) also saved.
My questions:
How easy is this to do?
How would I go about doing the above dynamically?
Thanks
--EDIT--
The images and operators are stored as .9.png files in my drawable folder. I have string-array contain my problems that I will randomly pull from and then display them to the screen.
In the past I would do the following:
public View buildProblem()
{
LinearLayout rtnView = new LinearLayout(ctx);
rtnView.setOrientation(LinearLayout.HORIZONTAL);
rtnView.setLayoutParams(new GridLayout.LayoutParams());
// Build LeftSide
Iterator<Integer> itor = buildLeftSide();
ImageView iv;
// loop through of iterator
while(itor.hasNext())
{
iv = new ImageView(ctx);
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setImageResource(itor.next());
itor.remove();
rtnView.addView(iv);
}
// Space
rtnView.addView(space);
// Operator
rtnView.addView(plusSign);
// Build LeftSide
itor = buildRightSide();
// another loop
while(itor.hasNext())
{
iv = new ImageView(ctx);
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setImageResource(itor.next());
itor.remove();
rtnView.addView(iv);
}
// Space
rtnView.addView(space);
// Equal Sign
rtnView.addView(equalSign);
// Space
rtnView.addView(space);
// return the view
return rtnView;
}
I was thinking of using ImageViews for the numbers to be displayed to the screen which I have used in the past but not sure if that is the best way to do it.
https://github.com/barakisbrown/MathTest -- Is one attempt at doing the above but I have now started to rewrite it from scratch so which is why I am asking for help.
Inside a ListFragment I have a ListView which contains an image and some text (See Previous Solved Question)
I briefly managed to get the solution to that question to work but its stopped working now.
I'm loading image Bitmaps in an AsyncTask which update the Adapter via adapter.notifyDataSetChanged();
when they finish downloading I store the Bitmap in an class member: Bitmap array named ICONS[] which I access directly from the ArrayAdapter to save memory.
There's various checks in place to make sure i'm not downloading images multiple times all of which are working but ill add them here anyway:
note i here is each entry in the ListView
ICONS[i] = null for all i until they are downloaded and ICONS[i] becomes a Bitmap image.
iconSet[i] = false for all i until image is downloaded and set (updated within adapter), this stops the resetting of the ImageView Bitmap if its already been set.
iconDownloading[i] = false for all i until the AsyncTask downloader starts
iconDownloaded[i] = false for all i until the AsyncTask downloader finishes
private class ArticleAdapter extends ArrayAdapter<String>{
private final Context context;
private final String[] values;
public ArticleAdapter(Context context, String[] values) {
super(context, R.layout.list_entry, values);
this.context=context;
this.values=values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_entry,parent,false);
TextView tv = (TextView) rowView.findViewById(R.id.label);
tv.setText(values[position]);
if(ICONS[position]!=null&&!iconSet[position]){//not null and not set
iconSet[position]=true;
System.out.println("ArticleListFragment: Page " + pageIndex + " Setting icon " + position);
ImageView iv = (ImageView) rowView.findViewById(R.id.logo);
iv.setImageBitmap(ICONS[position]);
}else if(!iconDownloading[position]&&!iconDownloaded[position]){
iconDownloading[position]=true;//Starting download
String iconUrl = ARTICLE_LIST.getArticle(position).getThumbnail();
if(iconUrl!=null&&!iconUrl.equals("")){
System.out.println("ArticleListFragment: Page " + pageIndex + " Downloading icon " + position);
new LoadThumbnail(position, iconUrl).execute();
}else{
System.out.println("ArticleFragment: Article " + position + " has no icon");
}
}
//iv.setImageResource(resId);//Change Image - All set to sport at the moment
return rowView;
}
}
I've added a few System.out calls aswell to check everything is been done in the correct order, as intended the:
System.out.println("ArticleListFragment: Page " + pageIndex + " Downloading icon " + position);
Comes first then the:
System.out.println("ArticleListFragment: Page " + pageIndex + " Setting icon " + position);
Which is right before the setting of the Bitmaps, so its getting to the right point, with the right Bitmap (i assume as i've used ICONS[position].size() which outputs about 4000 bytes) so i'm stuck wondering what's going wrong?
EDIT
Ive narrowed the problem down to the check if(!iconSet[position]) if i remove this the bitmaps are loaded correctly, but they are reloaded every time another bitmap is added to the ICONS array which for some reason triggers that if statement 4 times for 2 icons.
Why is it doing it 4 times? (twice per row entry) and why does that check make a difference?
I have a a set of 10 imageviews in my layout. I have given them sequential id's also as
android:id="#+id/pb1"
android:id="#+id/pb2"
Now I want to change background dynamically.
int totalPoi = listOfPOI.size();
int currentPoi = (j/totalPoi)*10;
for (i=1;i<=currentPoi;i++) {
imageview.setBackgroundResource(R.drawable.progressgreen);
}
Now inside the for loop I want to set the image view background dynamically. i,e if the currentpoi value is 3, background of 3 image views should be changed. What ever the times the for loop iterates that many image view's background should be changed. Hope the question is clear now.
Note : I have only 1 image progressgreen that need to be set to 10 image views
Finally I did this in the following way,
I placed all the id's in the array as
int[] imageViews = {R.id.pb1, R.id.pb2,R.id.pb3,R.id.pb4,R.id.pb5,R.id.pb6,R.id.pb7,R.id.pb8,R.id.pb9,R.id.pb10};
Now:
int pindex = 0;
for (pindex; pindex <currentPoi; pindex++) {
ImageView img = (ImageView) findViewById(imageViews[pindex]) ;
img.setImageResource(R.drawable.progressgreen);
}
Now, I am able to change the images dynamically.
#goto10. Thanks for your help. I will debug your point to see what went wrong in my side
Create an ImageView array:
ImageView views[] = new ImageView[10];
views[0] = (ImageView)findViewById(R.id.pb1);
...
views[9] = (ImageView)findViewById(R.id.pb10);
Now iterate the loop to set the background of images like this:
for (i=1;i<=currentPoi;i++)
{
views[i-1].setBackgroundResource(R.drawable.progressgreen);
}
you can do this by setting the name of drawables something like:
img_1, img_2, img_3...
for (i=1;i<=currentPoi;i++)
{
ImageView imageview=(ImageView) findViewById(getResources().getIdentifier("imgView_"+i, "id", getPackageName()));
imageview.setImageResource(getResources().getIdentifier("img_"+i, "drawable", getPackageName()));
}
Try this code.....
Create image Array..
private Integer[] mThumbIds = { R.drawable.bg_img_1, R.drawable.bg_img_2,
R.drawable.bg_img_3, R.drawable.bg_img_4, R.drawable.bg_img_5 };
And than modify your code
int totalPoi = listOfPOI.size();
int currentPoi = (j/totalPoi)*10;
for (i=1;i<=currentPoi;i++) {
imageview.setBackgroundResource(mThumbIds[i]);}
You could make an array of your ImageViews and then change them in your for loop.
ImageView views[] = new ImageView[10];
views[0] = (ImageView)findViewById(R.id.imageView0);
...
views[9] = (ImageView)findViewById(R.id.imageView9);
and then change your for loop to:
for (i=1;i<=currentPoi;i++) {
views[currentPoi].setBackgroundResource(R.drawable.progressgreen);
}
Arrays start at index 0, so make sure there's not an off-by-one error in here.
You'll need to give your ImageViews sequential ids, such as "#+id/pb1" and "#+id/pb2", etc.. Then you can get each of them in the loop like this:
for (i=1;i<=currentPoi;i++) {
// Find the image view based on it's name. We know it's pbx where 'x' is a number
// so we concatenate "pb" with the value of i in our loop to get the name
// of the identifier we're looking for. getResources.getIdentifier() is able to use
// this string value to find the ID of the imageView
int imageViewId = getResources().getIdentifier("pb" + i, "id", "com.your.package.name");
// Use the ID retrieved in the previous line to look up the ImageView object
ImageView imageView = (ImageView) findViewById(imageViewId);
// Set the background for the ImageView
imageView.setBackgroundResource(R.drawable.progressgreen);
}
Replace com.your.package.name with your application's package.
i am preparing one small game like jigsaw , for that i am using 9 imageview's with 9 different images in the layout. set the images to imageview at the time of starting those are actual images, after shuffle user will do sliding the images to complete puzzle, i want to check the modified image with actual image's, weather it's equal or not if those are equal popup a message, like gameover.
i tried like this
1.by using AND operator between the images(Drawables) but unlucky.
2.Using setLevel() for the images, compare those setLevel values with getLevel values for images after sliding still Unlucky.. here the problem is if i click on imageview one time getLevel() gives correct value, if i click more than once it gives zero value. Why it happens like this..
Please help me if you find any mistake in my code, otherwise guide me with good technique..
Xml code like this
<RelativeLayout
//9 imageview's
in jave code like this
if user will click on imageview it will swap the image's
img_View11.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(img_View21.getDrawable() == default_img ||
img_View12.getDrawable() == default_img) {
System.out.println("yes");
++click;
Noof_moves.setText("Moves: " +click);
ImageView iv = (ImageView)v;
d11 = iv.getDrawable();
prev_img = prev_imgView.getDrawable();
la11 = d11.getLevel();
System.out.println("d11 value is " +la11);
prev_imgView.setImageDrawable(d11);
img_View11.setImageDrawable(prev_img);
prev_imgView = img_View11;
check();
}
else { System.out.println("no"); }
}
});
void check(){
System.out.println("in checking condition");
if((lb11==la11) && (lb12==la12) && (lb13==la13) && (lb21==la21) && (lb22==la22)
&& (lb23==la23) && (lb31==la31) && (lb32==la32) && (lb33==la33)) {
Context c = getBaseContext();
System.out.println("gameover");
Toast.makeText(c, " GameOver ", Toast.LENGTH_SHORT).show();
}else{ System.out.println(" codition not checked "); }
}
//here lb=level before sliding
// la=level after sliding..
Ok, here is what you do for the solution.
maintain a new set of drawables marking them as original drawables that you had initially.
may be like
drawable og11 = imageView11.getDrawable();
do this part before shuffling. now you have original drawables, stored in the form of drawables.
After every click , check if og11 == imageView11.getDrawable(),... and so on for all the images in the jigsaw, if they match , it matches, else, they don't.
HTH.
I have a simple solution. Set serial number Integer tags to ImageViews using View.setTag(index) before jumbling(before preparing the puzzle.) Then everytime the user makes a move, loop through all the imageviews and check if they are in order. If out of order then puzzle is not completed yet.
class PuzzleItem {
Drawable puzzlepartImage;
int correctPosition;
public PuzzleItem(Drawable d, int index) {
puzzlepartImage = d;
correctPosition = index;
}
}
ArrayList<PuzzleItem> list = new ArrayList<PuzzleItem>();
for (int i = 0; i < 9; i++) {
list.add(new PuzzleItem(drawables[i], i));
}
Collections.shuffle(list);
//Create the views from this list and add to the layout serially.
// set the last view as emptyview.
On every move:
void onClick(View v) {
/* swap drawables */
Drawable clickedDrawable = v.getDrawable();
v.setDrawable(null);
mEmptyView.setDrawable(clickedDrawable);
mEmptyView = v;
/* swap tag integers */
Integer temp = (Integer)mEmptyView.getTag();
mEmptyView.setTag(v.getTag());
v.setTag(temp);
}
After every move check for completion:
for (int i = 0; i < 9; i++) {
if (imgView[i].getTag() != i) break;
}
if (i == 9)// puzzle completed.
why don't you use a gridView? and after each change, just check the items to see that images are in desired order
When you use == operator they are checking if both the objects are referencing the same object. But in your case they are 2 different objects.
You should set a tag to both the actual image and the other image. And check if they are both the same. That should work in your if condition.
For the drawable class i did notice a method setLevel and getLevel. You might be able to use this for your requirement.