How to swap images in a GridView (Android) - java

I'm working on a slider puzzle Android app, so I'm using a GridView to display 16 images representing tiles. One of the tiles will consist of a plain white image (representing the background). The idea is that if the user clicks on any tile neighboring the white tile, the selected tile and the white tile will switch positions.
I'm trying to implement this by setting the white tile to the tile selected by the user, and vice versa. I saved the position of the white tile (it starts off at position 15) in the variable masterTilePos, and using the ImageAdapter Integer array referring to the images in my R.drawable file, set the image at masterValPos to the image at the selected index, and the selected image to the white tile. However, when I run the program, the tiles only successfully switch the first time: after that, it doesn't work properly and the order of the tiles within the GridView is ruined. I think it may because the array is simply referring to the actual image objects, but I'm not sure how to what to do instead; it has already been three days since I ran into this problem. Here is my code:
//GRID VIEW
public class MainActivity extends ActionBarActivity {
int masterTilePos = 15;
GridView gridview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
//These methods check if a neighboring tile is white, if there is one, swap() is called
if(checkUp(position) || checkDown(position) || checkLeft(position) || checkRight(position)) {
swap(position);
}
}
});
}
public void swap(int pos) {
ImageAdapter updater = new ImageAdapter(this);
//This is where I try to switch the images, and seems to be the source of the problem
int val = updater.mThumbIds[masterTilePos];
updater.mThumbIds[masterTilePos] = updater.mThumbIds[pos];
updater.mThumbIds[pos] = val;
updater.notifyDataSetChanged();
gridview.setAdapter(updater);
gridview.invalidateViews();
masterTilePos = pos;
}
}
//IMAGE ADAPTER
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 4;
int height = metrics.heightPixels / 4;
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(width, height));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(1, 1, 1, 1);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// the array containing references to the images
public Integer[] mThumbIds = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.background
};
}
Can anyone please help me solve this so I can successfully switch the images within the grid? Thanks.

In onCreate you are doing:
gridview.setAdapter(new ImageAdapter(this));
So, you created adapter, without assign it to any variable. This is wrong!
Then, every swap you create new Adapter:
ImageAdapter updater = new ImageAdapter(this);
And you are setting it as current adapter:
gridview.setAdapter(updater);
This is wrong as well.
You must do in such a way:
OnCreate -> create adapter, assign it to objects's variable (property)
Then you need to work only with that variable.
And then, if you have a problem, debug your logic in SWAP method.
//GRID VIEW
public class MainActivity extends ActionBarActivity {
int masterTilePos = 15;
GridView gridview;
ImageAdapter imageAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
imageAdapter= new ImageAdapter(this);
gridview.setAdapter(imageAdapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
//These methods check if a neighboring tile is white, if there is one, swap() is called
if(checkUp(position) || checkDown(position) || checkLeft(position) || checkRight(position)) {
swap(position);
}
}
});
}
public void swap(int pos) {
//This is where I try to switch the images, and seems to be the source of the problem
int val = imageAdaptor.mThumbIds[masterTilePos];
imageAdapter.mThumbIds[masterTilePos] = imageAdapter.mThumbIds[pos];
imageAdapter.mThumbIds[pos] = val;
imageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
masterTilePos = pos;
}
}
//IMAGE ADAPTER
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 4;
int height = metrics.heightPixels / 4;
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(width, height));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(1, 1, 1, 1);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// the array containing references to the images
public Integer[] mThumbIds = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.background
};
}

Related

Passing images from one adapter to another

I have a gridView on my mainScreen fragment which contains imageViews initialized by my ImageAdapter.java class. I also have another fragment which also has a gridView which follows the same initialization process. What i want is to pass the selected imaveView's icon(which is stored in an Integer[] array) to the other fragment's gridView.
Here are my classes:
MainFragment.java [the part that handles the image passing]:
// When an item in the context menu gets selected, call a method
#Override
public boolean onContextItemSelected(MenuItem item) {
// Get some extra info about the contextMenu
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = info.position; // clicked view's position
if(item.getTitle().equals("Add Card to GLB")) {
addCardMessage(position, "added to GLB");
addSelectedCardToGlobalUserBox(position);
} else if (item.getTitle().equals("Add Card to JP")) {
addCardMessage(position , "added to JP");
} else
{
return false;
}
return false;
}
/**
* Creates a snackbar message, telling the user which card was added to which box
* #param id The position of the chosen card
* #param text Defines into which User Box the card was added
*/
private void addCardMessage(int id, String text) {
final Snackbar snackbar = Snackbar.make(gridView, id + " " + text ,Snackbar.LENGTH_LONG);
snackbar.setAction("Dismiss", new View.OnClickListener() {
#Override
public void onClick(View view) {
snackbar.dismiss();
}
});
snackbar.setActionTextColor(Color.MAGENTA);
snackbar.show();
}
private void addSelectedCardToGlobalUserBox(int position) {
ImageAdapter imageAdapter = new ImageAdapter(getContext());
UserBoxGlbImageAdapter userBoxGlbImageAdapter = new UserBoxGlbImageAdapter(getContext());
userBoxGlbImageAdapter.getGLBIconsList().add(imageAdapter.getmThumbIds(position));
int glbiconSize = userBoxGlbImageAdapter.getCount();
Toast.makeText(getActivity(), "Selected icon: " + imageAdapter.getmThumbIds(position), Toast.LENGTH_SHORT).show();
}
ImageAdapter.java [above fragment's adapter]:
public class ImageAdapter extends BaseAdapter {
Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
// If it's not recycled, initialize some attributes
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(225, 225));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
public Integer getmThumbIds(int index) {
return mThumbIds[index];
}
// References to our images
private Integer[] mThumbIds = {
R.mipmap.turvegitossj_phy,
R.mipmap.goget_ur_int,
R.mipmap.turgogetassj4_teq,
R.mipmap.turgotenksssj_uragl,
R.mipmap.lr_phy_trunks_ssj
};
}
SecondFragment.java:
public class UserBoxGLBFragment extends Fragment {
GridView globalGridView;
public UserBoxGLBFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_user_box_glb, container, false);
globalGridView = view.findViewById(R.id.userBoxGlbGridView);
globalGridView.setAdapter(new UserBoxGlbImageAdapter(getContext()));
return view;
}
}
SecondFragmentAdapter[the one to receive the image]:
public class UserBoxGlbImageAdapter extends BaseAdapter {
Context mContext;
public UserBoxGlbImageAdapter(Context c) {
mContext = c;
}
#Override
public int getCount() {
return mGLBIcons.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
// References to the images via a List
private List<Integer> mGLBIcons = new ArrayList<>();
// Used to add card icons from the mainScreenFragment
public List<Integer> getGLBIconsList() {
return mGLBIcons;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
// If it's not recycled, initialize some attributes
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(225, 225));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mGLBIcons.get(position));
return imageView;
}
}
So far, when i long-press and the context menu opens, i click on add card to GLB but the image doesn't pass to the 2nd fragmnet's gridView. From what i understand, the Integer that i am using to add the imageResource to the 2nd grid does not work properly. What do i need to do? Do i need to use a different var type for my receiver list?

java.file.io is not getting resolved out

I've been working on making a video gallery for myself and got stuck here. Followed this link for some references but still getting some problems:
For making thumbnails for the videos
Here is my code :
public class AddFragment extends Fragment {
private ImageButton imageButton;
private GridView gridView;
private File files;
ArrayList<File> list;
public AddFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_add, container, false);
imageButton = (ImageButton) view.findViewById(R.id.gotoButton);
gridView = (GridView) view.findViewById(R.id.grid_view);
gridView.setAdapter(new ImageAdapter(getContext()));
list = videoReader(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
//for making the button visible as ssonas the item gets selected
imageButton.setVisibility(view.VISIBLE);
}
});
return view;
}
ArrayList<File> videoReader(File root) {
ArrayList<File> arrayList = new ArrayList<>();
File[] file = root.listFiles();
for(int i=0;i<file.length;i++){
if(file[i].isDirectory()){
}else{
if(file[i].getName().endsWith(".mp4")){
arrayList.add(file[i]);
}
}
}
return arrayList;
}
public class ImageAdapter extends BaseAdapter{
private Bitmap bitmap;
private final Context context;
private ImageAdapter(Context c){
context = c;
}
//for the video numbers
#Override
public int getCount() {
return list.size();
}
//for getting the video items position vise
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ImageView picturesView;
if (convertView == null) {
picturesView = new ImageView(context);
if(list.get(position).contains(".jpg"))
{
bitmap = BitmapFactory.decodeFile(list.get(position)); //Creation of Thumbnail of image
}
else if(list.get(position).contains(".mp4"))
{
bitmap = ThumbnailUtils.createVideoThumbnail(list.get(position), 0); //Creation of Thumbnail of video
}
picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
picturesView.setPadding(8, 8, 8, 8);
picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));
}
else
{
picturesView = (ImageView)convertView;
}
return picturesView;
}
} }
The problems I'm getting are in my ImageAdapter class in getView method
These are :
1. In the if(list.get(position).contains(".jpg")) //cannot resolve contains
2. In bitmap = BitmapFactory.decodeFile(list.get(position)); //saying the decodeFile(java.lang.string) from Bitmapfacotory cannot be applied to (java.file.io)
P.S. for the second option I tried doing that after getting reference from this link but failed:
Java contradicting behavior resolved
Try this.
if(list.get(position).contains(".jpg"))
{
bitmap = BitmapFactory.decodeFile(list.get(position).toString());
}
list.get(position) is File object and you need to pass String object so just make it String by writing .toString().
contains expect to see the same object type as the list items. if you want to check if the file is an image read this: Android: How to check if file is image?
Decode file expects to get a file url and not a file object. see here how to use it: Bitmapfactory example

parent.getMeasuredWidth() and parent.getMeasuredHeight() return 0 in ImageAdapter for GridView

I have 6 drawable images. I put this images in a GridView in 2x3 if it's portraite and 3x2 if it's landscape, but i have a problem: if i try to put measures based on parent.getMeasuredWidth() and parent.getMeasuredHeight();
first drawable have always 0 as width and hight;
From LOG:
w: 0 h:0
Code ImageAdapter:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {mContext = c;}
public int getCount() {return mThumbIds.length;}
public Object getItem(int position) {return null;}
public long getItemId(int position) {return 0;}
public View getView(int position, View convertView, final ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
int width = parent.getMeasuredWidth();
int height = parent.getMeasuredHeight();
int orientation = parent.getResources().getConfiguration().orientation;
int vh,vo;
if(orientation == 1){
vh = width/2;
vo = height/3;
} else {
vh = (width/3);
vo = (height/2);
}
Log.e(TAG,"w: "+vh+" h:"+vo);
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(vh, vo));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.gradient_bg_t1,
R.drawable.gradient_bg_t2,
R.drawable.gradient_bg_t4,
R.drawable.gradient_bg_t5,
R.drawable.gradient_bg_t6,
R.drawable.gradient_bg_t3
};
}
Code MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
}
});
}
Thank you.
it returns zero because the parent view isnt drawn yet. you can post your code to the parent view so it runs after parent view was drawn.
use below code:
parent.post(new Runnable() {
#Override
public void run() {
int w = parent.getMeasuredWidth();
int h = parent.getMeasuredHeight();
...
}
});
I already tried the code of #Amir Ziarati in ImageAdapter (found it in StackOverflow), but i can't get the values out of scope.
After i drink a little coffee i changed the code a litle:
I created in ImageAdapter 2 new int variable w,h for width and height:
private Context mContext;
private int w,h;
public ImageAdapter(Context c,int width,int height) {
mContext = c;
w = width;
h = height;
}
and in MainActivity:
gridview = (GridView) findViewById(R.id.gridview);
gridview.post(new Runnable() {
#Override
public void run() {
int w = gridview.getMeasuredWidth();
int h = gridview.getMeasuredHeight();
gridview.setAdapter(new ImageAdapter(MainActivity.this,w,h));
}
});
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
}
});
And it's working.

Background color or Images shuffling on scrolling in recyclerview?

I am wondering that my images and color of layouts shuffling when i scrolls downwards or upwards, I created cardview using recyclerview. and set an image(changes color on click like to know if its user's favourite item) and setbackgroundcolor(randomly chossen) to the parent layout to make cardview attractive. but when i scrolls
1. the image that image changes position,
2. the layout background changes color automatically.
I am posting my adapter's code here.
public class TOAdapter extends RecyclerView.Adapter<TOAdapter.ViewHolder> {
JSONArray jsonArray;
private String title;
private String image;
private ImageLoader imageLoader;
private String subtitle;
private String subti;
private Context context;
private ImageView clip;
public TOAdapter(JSONArray jsonArray) {
this.jsonArray = jsonArray;
}
// Create new views (invoked by the layout manager)
#Override
public TOAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.top_twenty_list, parent, false);
final ViewHolder viewHolder = new ViewHolder(itemLayoutView);
final Random random = new Random(System.currentTimeMillis());// We add 155 since we want at least 155 in each channel.// Then we add to it a random number between 0 and 100.
int r = 155 + random.nextInt(101);
int g = 155 + random.nextInt(101);
int b = 155 + random.nextInt(101);
int color = Color.rgb(r, g, b);
viewHolder.frame.setBackgroundColor(color);
viewHolder.layer.setBackgroundColor(color);
clip = (ImageView) itemLayoutView.findViewById(R.id.ic_clip);
clip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int iColor = Color.parseColor("#0000FF");
int red = (iColor & 0xFF0000) / 0xFFFF;
int green = (iColor & 0xFF00) / 0xFF;
int blue = iColor & 0xFF;
float[] matrix = {0, 0, 0, 0, red
, 0, 0, 0, 0, green
, 0, 0, 0, 0, blue
, 0, 0, 0, 1, 0};
ColorFilter colorFilter = new ColorMatrixColorFilter(matrix);
clip.setColorFilter(colorFilter);
}
});
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final ViewHolder viewHolder, int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
// myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/RobotoCondensedBoldItalic.ttf");
try {
JSONObject obj = jsonArray.getJSONObject(position);
title = obj.getString("title");
image = obj.getString("brand_logo");
subtitle = obj.getString("sub_title");
} catch (JSONException e) {
e.printStackTrace();
}
viewHolder.txtViewTitle.setText(subtitle);
viewHolder.subtitle.setText(title);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
String full_Url = "http://mycompany/assets/new" + image;
viewHolder.thumbnail.setImageUrl(full_Url, imageLoader);
viewHolder.btn_get_deal.setTag(position);
viewHolder.btn_get_deal.setOnClickListener(new View.OnClickListener() {
public JSONObject obj;
public ArrayList<String> offerlist = new ArrayList();
#Override
public void onClick(View view) {
Intent offerpage = new Intent(AppController.getInstance().getApplicationContext(), OfferDetails.class);
Integer pos = (Integer) view.getTag();
try {
obj = jsonArray.getJSONObject(pos);
offerpage.putExtra("jsonObj", obj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
//offerpage.getParcelableArrayListExtra(offerlist);
offerpage.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
AppController.getInstance().getApplicationContext().startActivity(offerpage);
}
});
//viewHolder.txtViewTitle.setTypeface(myTypeface);
}
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder {
private final NetworkImageView thumbnail;
private final RelativeLayout frame;
private final RelativeLayout layer;
public TextView txtViewTitle;
public TextView subtitle;
public ImageView clip;
public CardView btn_get_deal;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.txttitle_toptwenty);
subtitle = (TextView) itemLayoutView.findViewById(R.id.sub_title_toptwenty);
thumbnail = (NetworkImageView) itemLayoutView.findViewById(R.id.thumbnail_topwenty);
frame = (RelativeLayout) itemLayoutView.findViewById(R.id.frame);
layer = (RelativeLayout) itemLayoutView.findViewById(R.id.layer);
btn_get_deal = (CardView) itemLayoutView.findViewById(R.id.card_view);
}
}
// Return the size of your itemsData (invoked by the layout manager)
#Override
public int getItemCount() {
return jsonArray.length();
}
}
I have created a working example of what you are trying to accomplish. The source of the errors you experience is mostly that you don't understand view recycling. I am not going to explain the whole thing to you now, but anyway here is the example:
For the example I used this layout for each row:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/background"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
I used this model:
public class ExampleModel {
private final int mColor;
private final String mText;
public ExampleModel(int color, String text) {
mColor = color;
mText = text;
}
public int getColor() {
return mColor;
}
public String getText() {
return mText;
}
}
And this view holder:
public class ExampleViewHolder extends RecyclerView.ViewHolder {
private final FrameLayout mBackground;
private final TextView mTextView;
public ExampleViewHolder(View itemView) {
super(itemView);
mBackground = (FrameLayout) itemView.findViewById(R.id.background);
mTextView = (TextView) itemView.findViewById(R.id.textView);
}
public void bind(ExampleModel model) {
mBackground.setBackgroundColor(model.getColor());
mTextView.setText(model.getText());
}
}
As you can see nothing special, the Adapter implementation is equally simple:
public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {
private final LayoutInflater mInflater;
private final List<ExampleModel> mModels;
public ExampleAdapter(Context context, List<ExampleModel> models) {
mInflater = LayoutInflater.from(context);
mModels = models;
}
#Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView = mInflater.inflate(R.layout.item_example, parent, false);
return new ExampleViewHolder(itemView);
}
#Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
final ExampleModel model = mModels.get(position);
holder.bind(model);
}
#Override
public int getItemCount() {
return mModels.size();
}
}
And you use the whole thing like this:
final Random mRandom = new Random(System.currentTimeMillis());
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
final List<ExampleModel> models = new ArrayList<>();
for (int i = 0; i < 100; i++) {
final int randomColor = generateRandomPastelColor();
models.add(new ExampleModel(randomColor, String.valueOf(i)));
}
final ExampleAdapter adapter = new ExampleAdapter(getActivity(), models);
recyclerView.setAdapter(adapter);
}
public int generateRandomPastelColor() {
final int baseColor = Color.WHITE;
final int red = (Color.red(baseColor) + mRandom.nextInt(256)) / 2;
final int green = (Color.green(baseColor) + mRandom.nextInt(256)) / 2;
final int blue = (Color.blue(baseColor) + mRandom.nextInt(256)) / 2;
return Color.rgb(red, green, blue);
}
This should do what you are looking for and you can use it as an example of how to implement your Adapter.
I got the same problem ,when i used the radioButton in my listView row, I solved it. As in every scrolling the Cache is cleared, you have to store the changed data in every row. just check my code
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
// if(position==0)
// Toast.makeText(context, ""+QuestionViewPageAdapter.mRadioGroupData, Toast.LENGTH_SHORT).show();
final ViewHolder viewHolder;
View row=convertView;
radioButton=new RadioButton[Integer.parseInt(mNoOfCategoryGreading)];
LayoutInflater inflater =LayoutInflater.from(context);//(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.question_row, parent, false);
viewHolder=new ViewHolder();
viewHolder.tv_qContent=(TextView)row.findViewById(R.id.tv_question);
viewHolder.rg=(RadioGroup)row.findViewById(R.id.rgrp);
for(int i=0;i<Integer.parseInt(mNoOfCategoryGreading);i++)
{
radioButton[i]=new RadioButton(context);
radioButton[i].setLayoutParams(new RadioGroup.LayoutParams(0, LayoutParams.WRAP_CONTENT,1f));
//1f for layout_weight="1"
radioButton[i].setId(i);
radioButton[i].setText(""+(i+1));
viewHolder.rg.addView(radioButton[i]);
}
row.setTag(viewHolder);
for(int i=0;i<QuestionViewPageAdapter.mRadioGroupData.size();i++){
int p=Integer.parseInt(""+QuestionViewPageAdapter.mRadioGroupData.get(i).get("position"));
String id=QuestionViewPageAdapter.mRadioGroupData.get(i).get("Id");
if(p!=-1 && id.equals(""+data.get(position).get(AppData.question_Set_category_QuestionID)))
{//radioButton[p].setSelected(true);
viewHolder.rg.check(p-1);}
//Toast.makeText(context, "Yes "+p, Toast.LENGTH_LONG).show();}
}
viewHolder.tv_qContent.setText((position+1)+". "+data.get(position).get(AppData.question_Set_category_QuestionContent));
viewHolder.tv_qContent.setTypeface(typeface_muso_regular300);
viewHolder.rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// TODO Auto-generated method stub
String s=data.get(position).get(AppData.question_Set_category_QuestionID);
isAvailabel(s);
int radioButtonID = viewHolder.rg.getCheckedRadioButtonId();
View radioButton = viewHolder.rg.findViewById(radioButtonID);
int idx = viewHolder.rg.indexOfChild(radioButton);
HashMap<String, String> map=new HashMap<String, String>();
map.put("position", ""+(idx+1));
map.put("Id", ""+data.get(position).get(AppData.question_Set_category_QuestionID));
map.put("CategoryId", ""+mCategoryId);
QuestionViewPageAdapter.mRadioGroupData.add(map);
}
});
return row;
}
private void isAvailabel(String qId){
for(int i=0;i<QuestionViewPageAdapter.mRadioGroupData.size();i++){
if(qId.equals(QuestionViewPageAdapter.mRadioGroupData.get(i).get("Id"))){
position=i;
QuestionViewPageAdapter.mRadioGroupData.remove(i);
}
}
}
class ViewHolder {
TextView tv_qContent ,tv_1,tv_2,tv_3;
RadioGroup rg;
RadioButton rBtn1,rBtn2,rBtn3,rBtn4,rBtn5;
}
After days of struggle and headache, i have found a very simple solution.
In your adapter you just need to override 2 methods.
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
Helped me resolve the shuffling issue of recycler view.
In my case overriding getItemId and setting sethasStableIds to true solved the shuffling issue.
in adapter:
#Override
public long getItemId(int position) {
Object listItem = feeds.get(position);
return listItem.hashCode();
}
in main activity/fragment :
adapter = new FeedAdapter(feeds, getContext());
adapter.setHasStableIds(true);

Image Switcher Issue in Android

I am using image switcher to display several picture.
I have initialized the final Integer[] imageIDs = {} and use declare elements in it in If-Else statement which locates in the OnCreate. I do so because for each different places I would like to input different pictures into the imageIDs. In this example is "UK". So if another places was chosen, the imageIDs should have different pictures refer to.
Unfortunately there was nothing in the imageswitcher when I run the apps.
final Integer[] imageIDs = {};
private ImageSwitcher imageSwitcher;
DBAdapter dbAdapter;
final Context context = this;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.attraction_details);
Intent intent = getIntent();
String selectedSubArea = intent.getStringExtra("SelectedSubArea");
Button btnAddToTrip = (Button) findViewById(R.id.btnAddToTrip);
Button btnAddToFav = (Button) findViewById(R.id.btnAddToFav);
Button btnShowAttractionLocation = (Button) findViewById(R.id.btnShowAttractionLocation);
TextView description = (TextView) findViewById(R.id.description);
TextView address = (TextView) findViewById(R.id.address);
TextView openingHours = (TextView) findViewById(R.id.openingHours);
TextView contactNo = (TextView) findViewById(R.id.contactNo);
if (selectedSubArea.equals("UK"))
{
this.setTitle(selectedSubArea);
description.setText("desc");
address.setText("add");
latitude = 2.0057378;
longitude = 103.3760577;
openingHours.setText("n/a");
contactNo.setText("n/a");
final Integer[] imageIDs = {
R.drawable.uk_1,
R.drawable.uk_2,
R.drawable.uk_3};
name = selectedSubArea;
desc = description.toString();
add = address.toString();
opening = openingHours.toString();
contact = contactNo.toString();
dbAdapter = new DBAdapter(context);
imageSwitcher = (ImageSwitcher) findViewById(R.id.switcher1);
imageSwitcher.setFactory(this);
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
Gallery gallery = (Gallery) findViewById(R.id.gallery1);
gallery.setAdapter(new ImageAdapter(this));
gallery.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
imageSwitcher.setImageResource(imageIDs[position]);
}
});
}
}
public View makeView()
{
ImageView imageView = new ImageView(this);
imageView.setBackgroundColor(0x00000000);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
return imageView;
}
public class ImageAdapter extends BaseAdapter
{
private Context context;
private int itemBackground;
public ImageAdapter(Context c)
{
context = c;
//---setting the style---
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
//---returns the number of images---
public int getCount()
{
return imageIDs.length;
}
//---returns the ID of an item---
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView = new ImageView(context);
imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
Your global imageIDs array length is ZERO so its displayed nothing. You can't use final array in your case as the objects can varies depending on your selectedSubArea
Else
You can change your ImageAdapter like this then it will work
public class ImageAdapter extends BaseAdapter
{
private Context context;
private int itemBackground;
Integer[] local_imageIDs
public ImageAdapter(Context c, Integer[] local_imageIDs)
{
context = c;
this.local_imageIDs = local_imageIDs;
//---setting the style---
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
//---returns the number of images---
public int getCount()
{
return local_imageIDs.length;
}
//---returns the ID of an item---
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView = new ImageView(context);
imageView.setImageResource(local_imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
then set this adapter as
gallery.setAdapter(new ImageAdapter(this, imageIDs));
And remove the global imageIDs

Categories