I am using ExtendedCalendarView to draw year and month days
here is the link of ExtendedCalendarView enter link description here
Now I get Calendar programmatically and then selected day which I want, should change their background image
Just like
ExtendedCalendarView extendedCalendarView = (ExtendedCalendarView) findViewById(R.id.calendar);
GridView calendar = (GridView) extendedCalendarView.findViewById(999);
calendar.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int pos,long id) {
TextView dayTV = (TextView)view.findViewById(R.id.textView1);
dayTV.setBackgroundResource(R.drawable.ic_launcher);
}
}
Now I face issue, the issue is to set background, when API level less than 17 its does not seems to work, the cell selected which I want to select but its background does not change.
Its working with XML
android:background="#drawable/ic_launcher"
and there is no issue with that but I have constraints which prevent me that day could not selected, that's why I could not use XML.
Is there any way to change background when API less then 17
Thanks
// your code looks good if textview is inside GridView;
This code is for textview outside:
ExtendedCalendarView extendedCalendarView = (ExtendedCalendarView) findViewById(R.id.calendar);
GridView calendar = (GridView) extendedCalendarView.findViewById(999);
TextView dayTV = (TextView) findViewById(R.id.textView1);
calendar.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView adapter, View view, int pos,long id) {
dayTV.setBackgroundResource(R.drawable.ic_launcher);
}
}
Related
So I am trying to create a challenge game where you can have 2 options to pick from, I have 2 card views setup in a recycler view setup, how would I change the values in them to get a new challenge with the click of a button from the main activity if a user wanted a new challenge?
I am fetching the data from each battle at random using an SQLite database.
My onBindViewHolder
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
SQLiteDatabase sqLiteDatabase = faceMashDatabaseHelper.getReadableDatabase();
cursor = sqLiteDatabase.query("images", new String[]{"id","filename","name"},null,null,null,null,null);
MyViewHolder myViewHolder = (MyViewHolder) holder;
int position1 = (int)(Math.random()*(faceMashDatabaseHelper.getCount()-0+1)+0);
cursor.moveToPosition(position1);
String filename = cursor.getString(cursor.getColumnIndex("filename"));
String name = cursor.getString(cursor.getColumnIndex("name"));
CardView cardView = myViewHolder.getCardView();
ImageView imageView = (ImageView) cardView.findViewById(R.id.imageView);
TextView nameView = (TextView) cardView.findViewById(R.id.nameView);
nameView.setText(name);
File file = context.getFileStreamPath(filename);
if(file.exists()){
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
imageView.setImageBitmap(bitmap);
}
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String name = nameView.getText().toString();
listener.onClick(position,name);
}
}); //This on click is for the card views themselves.
}
My onClick at the current moment, I'm using a toolbar option
case R.id.newbattle:
faceMashAdapter.notifyDataSetChanged();
First of all, you should never do heavy work in onBindViewHolder since it will be called every time your View is recreated after it was recycled (because it was unused).
You should query your Database outside of the Adapter instead and occupy a List with your queried data. Your List should have as many entries as your RecyclerView has entries. Then you can use the position parameter in onBindViewHolder to always get the correct data for the entry (list.get(position)).
This way you can just change the content of your List and notify the Adapter which items have changed via notifyItemChanged (or if all items should be refreshed, use notifyDataSetChanged). That way the content of the Adapter is refreshed.
So what you should do in your onClick is update the content of your List and notify the Adapter.
I have a custom listview, each item have a imagebutton, i want to change image of each imagebutton immediately when I click. Each item in custom listview is a object named baiHat{}.
I use BaiHatAdapter like this, but it not chane immediately, i must scroll listview to see change.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=this.context.getLayoutInflater();
View row=inflater.inflate(this.resource, null);
TextView txtMs = (TextView) row.findViewById(R.id.ms);
TextView txtBh = (TextView) row.findViewById(R.id.bh);
TextView txtCs = (TextView) row.findViewById(R.id.cs);
TextView txtLr = (TextView) row.findViewById(R.id.lr);
ImageButton imglike = (ImageButton) row.findViewById(R.id.imageButton);
final BaiHat baiHat = this.objects.get(position);
txtMs.setText(baiHat.getTxtms());
txtBh.setText(baiHat.getTenBh());
txtCs.setText(baiHat.getTxtcs());
txtLr.setText(baiHat.getTxtLr());
imglike.setImageResource(baiHat.getImg());
imglike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xulythich(baiHat);
}
});
return row;
}
private void xulythich(BaiHat baiHat) {
if(baiHat.getThich()){
baiHat.setThich(false);
baiHat.setImg(R.drawable.addfav);
}else{
baiHat.setThich(true);
baiHat.setImg(R.drawable.added);
}
}
Create a selector file and assigning it as src would work. But as a better approach you can try to change it to togglebutton, since imageview is not meant to be clickable and give it the background of selector source.
It will just look like any imageview but with the capability of being clickable and changing its background from the selector file.
Is it possible to have methods and actual coding inside each item for a GridView?
The app that I am attempting to create is a currency converter, and I am currently displaying 3 images in the gridView: Euros, Pesos, and Rupees.
Once the user clicks on one, I want the open to open up a new XML which displays a textView. The user enters the value of US dollars in the textView and clicks the compute button. The app then displays the converted amount in the bottom of the screen.
The problem is that I am unable to figure out how to open up a new XML every time a picture is clicked on in the gridView. Assuming that I am able to do this, I am also unsure of where to place the code that goes behind the conversions. Would I make a new .java or just place is all in MainActivity.java?
Thanks.
What you might be best doing is when the user clicks on a currency it takes them to another activity where you would then load another xml for whatever you want to show.
In order to detect which item had been clicked you can implement an onItemClickListener for example
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//this assumes you give the gridview a list of currency which it then displays. Here we get the currency selected to then pass to our new activity
String selectedCurrency = myArrayOfCurrencies.get(position);
//then start new activity and give it the currency. This means we won't have to create an activity for each currency. You just need to create 1 and then based on what currency you give it will change the functionality
Intent intent = new Intent(this, Converter.class);
Intent.putExtra("currency", selectedCurrency);
startActivity(intent);
}
First you should be able to detect the clicks on each item of the GridView by calling the setOnItemClickListener() method.
If you set the clicklistener and you still can't detect the clicks, then most probably you need to add those attribtutes to your imageView in the xml
android:focusable="false"
android:focusableInTouchMode="false"
Second, once you are able to detect the clicks you can start new activity or add fragment that contains that edit text that will promote the user to enter the value.
Third, I would suggest to put the code responsible for the currency conversion in a class separately and create static methods that takes a value and convert it to the other curreny such as:
public class CurrencyConverter {
public static double convertToRupees (String currencyType, double currencyValue){
....
return currencyInRupees;
}
}
and by the way I would suggest you to use RecyclerView with grid layout manager instead of GridView.
I would create more classes.
You asked how to open a different XML file for each gridView item.
Create a custom adapter that extends BaseAdapter.
Override getView and for each view attach the right Xml file, according to the position.
For example:
YourActivity.java:
GridView gridView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gridView = (GridView) findViewById(R.id.gridView);
gridView.setAdapter(new MyAdapter(getApplicationContext());
}
MyAdapter.java:
...
#Override
public int getCount() {
return XmlArr.length;
}
#Override
public Object getItem(int position) {
return XmlArr[position];
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Xml myXml = (Xml) getItem(position);
Holder holder;
if (convertView == null) {
// Set your view's layout. Consider using LayoutInflater.
// Use a static holder to prevent re-initialization:
holder = new Holder();
// holder.textView = ...
// holder.Xml = ...
// Or whatever you decided to have in each gridView item.
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.Xml = myXml;
...
return convertView;
}
static class Holder() {
TextView tv;
Xml xml;
...
}
I assumed you would used an Xml array (xmlArr).
Now you have option to play with each gridView item as you wish. You can set each view/button/textView an onItemClickListener, or you can also set the whole gridView an onItemClickListener (from YourActivity.java).
Hope this helps.
I have the following OnCreateMethod()
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_siege_main);
mContext = getApplicationContext();
gridview = (GridView) findViewById(R.id.gridview_board);
initialBoard = new Board();
initialBoard.generate(Globals.rand_width,
Globals.rand_height,
Globals.rand_low,
Globals.rand_high);
gridview.setAdapter(new BoardAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//updateGameState(initialBoard);
}
});
updateGameState(initialBoard);
//typography
TextView boardName = (TextView) findViewById(R.id.textview_board_name);
boardName.setText("Uncharted Territory");
Toast.makeText(SiegeMainActivity.this, "Uncharted Territory loaded", Toast.LENGTH_SHORT).show();
Typeface face = Typeface.createFromAsset(getAssets(),
"fonts/calibri-1.ttf");
boardName.setTypeface(face);
TextView pl1Name = (TextView) findViewById(R.id.textViewPlayer1Name);
face = Typeface.createFromAsset(getAssets(),
"fonts/calibri-1.ttf");
pl1Name.setTypeface(face);
TextView pl2Name = (TextView) findViewById(R.id.textViewPlayer2Name);
face = Typeface.createFromAsset(getAssets(),
"fonts/calibri-1.ttf");
pl2Name.setTypeface(face);
}
and my updateGameState() method is like this:
private void updateGameState(Board b) {
int [] vals = b.getLinearVals();
int [] plays = b.getLinearPlays();
int [] score = b.getScore();
int turns = b.getTurns();
Button tile;
//updating board
for(int i=0;i<gridview.getChildCount();i++){
tile = (Button)gridview.getChildAt(i);
tile.setText(""+vals[i]);
if(plays[i]==1)
tile.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_default_normal_green));
else if (plays[i]==2)
tile.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.btn_default_normal_blue));
}
//Setting the score
Button pl1Score, pl2Score;
pl1Score = (Button) findViewById(R.id.buttonPlayer1Score);
pl2Score = (Button) findViewById(R.id.buttonPlayer2Score);
pl1Score.setText(""+score[0]);
pl2Score.setText(""+score[1]);
}
When I call updateGameState() in OnCreate after creating the adapter, it should fill the buttons with some values. But it doesn't seem to work. But when I do the same thing on a click (commented out in the click listener), it seems to work fine. I want to populate the values on loading the page. Can somebody help me?
You need to let the GridView know that the data has changed. If you are dynamically changing the data in the ArrayAdapter, you need to call BoardAdapter.notifyDataSetChanged() so the GridView can "refresh" itself with the new data.
In your case, you need to create a reference to you new BoardAdapter and then use that to call the notifyDataSetChange() method.
private BoardAdapter boardAdapter = null;
protected void onCreate(Bundle savedInstanceState) {
// your things
boardAdapter = new BoardAdapter(this);
gridview.setAdapter(boardAdapter);
// more things
}
private void updateGameState(Board b) {
// update your data
boardAdapter.notifyDataSetChanged();
}
Edit: You mentioned in the comment that you tried using an ArrayAdapter and it didn't work for you... maybe try this, which says to use the GridViews invalidateViews() method. gridView.invalidateViews()
Have a look at this SO question & answer here:
How to refresh a GridView?
I had a similar problem, but couldn't get it to even refresh on a button click, even tho items were being changed and added. In my case, the trick, as it turns out, was to recreate the (in your case) BoardAdapter with the new/updated list of items, and then reassign it to the gridview.
gridViewAdapter = new MyGridViewAdapter(this, blah, yourUpdatedItems);
discoverGridView.InvalidateViews();
discoverGridView.Adapter = gridViewAdapter;
I am sure there has to be a better, more reactive, way of doing it, but this at least got my proof of concept up and running.
I have an activity which consists of a GridView with multiple (different) images. When the user clicks on one image, a customized dialog box shows up in which an enlarged version of the image appears as well as some text below.
What I want accomplished: the image shown in the dialog box must correspond to the chosen image in the GridView. I thought that I could change the image resource in the onItemClick method, but the application crashes instead (only when I use the setImageResource command).
Here is the code:
public class Releases extends OptionsActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.releases);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ReleasesImgAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
//Toast.makeText(Releases.this, "" + position, Toast.LENGTH_SHORT).show();
if (position == 0)
{
CustomizeDialog cdWCE = new CustomizeDialog(Releases.this, R.layout.releases_popup);
ImageView wce = (ImageView)findViewById(R.id.rlsImg);
wce.setImageResource(R.drawable.image2);
cdWCE.show();
}
}
});
}
}
releases.xml simply consists of a GridView.
I can't debug the program because my Eclipse debugging haven't been working for a while now.
Try finding the ImageView in the actual dialog where you set the layout (e.g.
ImageView wce = (ImageView)cdWCE.findViewById(R.id.rlsImg);