I my app I am fetch some text data from the server and showing this text data in the TextView. Here is something works fine. I am add an little arrow ImageView right to the TextView and this TextView is expandable so when TextView is more then 2 lines and if anyone click this TextView it expand and again click to shrink and I am also add an little arrow image right to the TextView (so user understant that it is an expandable text), here is everything is fine all code are works perfectly but now I want to remove this litter arrow image when the TextView is under 2 lines and when TextView is more then 2 lines it show. I want to tell you one more thing that I am also add a rotation in the arrow image so when the user click the text the little arrow image rotate the 180 degree and also text is expand and when user click the text second time arrow image again rotate to his previous position and text is shrink in 2 lines.
I want to remove this little arrow when the text is under 2 lies I do not want to remove the arrow image when text line more then 2, I'm guessing you understand.
I am new to the Java Code and I am learning is language so now I want to learn how to do this implementation in my app, I have add my code below so that you can understand batter.
textViewMyVideoTitle.setText(videoLists.get(0).getVideo_title());
my_title_layout_expand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isTextViewClicked) {
//This will shrink textview to 2 lines if it is expanded.
textViewMyVideoTitle.setText(videoLists.get(0).getVideo_title());
myTitleImageView.setRotation(imageView.getRotation() + 0);
myTitleImageView.setVisibility(View.VISIBLE);
textViewMyVideoTitle.setMaxLines(2);
isTextViewClicked = false;
} else {
//This will expand the textview if it is of 2 lines
textViewMyVideoTitle.setText(videoLists.get(0).getVideo_title());
myTitleImageView.setRotation(imageView.getRotation() - 180);
myTitleImageView.setVisibility(View.VISIBLE);
textViewMyVideoTitle.setMaxLines(Integer.MAX_VALUE);
isTextViewClicked = true;
}
}
});
So anybody can help me to achieve this code
As you say, your text doesnt have more than 2 lines, so your function wont work until the text has more than 2 lines.
You may try to use TextView's getLineCount() method to get this info and decide.
So I mean outside your onClickListener do something like this:
if (textViewMyVideoTitle.getLineCount() <= 2) {
my_title_layout_expand.setVisibility(View.VISIBLE);
} else {
my_title_layout_expand.setVisibility(View.GONE);
}
Or since it gives you the right number only after layout been 'rendered' you might need the following:
textViewMyVideoTitle.post(new Runnable() {
#Override
public void run() {
// Get the line count and put the if-else statement here
}});
Related
I was designing an Instagram story type template. I am stuck at a very weird problem. I have used recycler view in the main activity.
MainActivity: (This is just the layout shown. I have change the orientation to Horizontal).
My layout:
Then I have designed a custom adapter and in the layout I have used a linearLayout. When clicked on each view It opens a new Activity which shows the whole story content.
Just like in Instagram when a user opens any story, the user can click on the right side of the screen to get to the next story, or left of the screen to get to the previous one. I tried to implement this same functionality. Opening the story was implemented successfully. The problem comes when I added the functionality of right and left click on the screen. I added two button; one to the right and one to the left. The problem is like, if there are currently 3 views visible, then I can navigate in between these stories only and not to the stories which are not visible in the screen because of the recycler view.
The below code is for right and left clicks
leftArrow = findViewById(R.id.leftArrow);
leftArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(myAdapter.currentPosition - 1 >= 0) {
int firstVis = MainActivity.linearLayoutManager.findFirstVisibleItemPosition();
MainActivity.linearLayoutManager.scrollToPosition(firstVis - 1);
rightOrLeftClicks(myAdapter.currentPosition - 1);
}
}
});
rightArrow = findViewById(R.id.rightArrow);
rightArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(myAdapter.currentPosition + 1 < myAdapter.localDataSet.length) {
int lastVis = MainActivity.linearLayoutManager.findLastVisibleItemPosition();
MainActivity.linearLayoutManager.scrollToPosition(lastVis + 1);
rightOrLeftClicks(myAdapter.currentPosition + 1);
}
}
});
}
Below code is of the function rightOrLeftClicks
public void rightOrLeftClicks(int position) {
finish();
Log.d("rl", "working");
nextView = MainActivity.linearLayoutManager.getChildAt(position);
Log.d("ll", "The last element is " + MainActivity.linearLayoutManager.findLastVisibleItemPosition());
if(nextView != null)myAdapter.onClickView(position, myAdapter.localDataSet[position].symptom, nextView);
}
Below code is for onClickView, It is same code for clicking any view (Story) or clicking the right or left buttons. Basically I just opened the another activity by passing an intent with the next or previous view I obtained when clicked on right or left respectively.
public static void onClickView(int position, String element, View v) {
Intent intent = new Intent(v.getContext(), MainActivity2.class);
idPosition = "";
idPosition = element;
ArrayList<String> passingContent = new ArrayList<>();
currentPosition = position;
passingContent.add(localDataSet[position].description);
passingContent.add(localDataSet[position].imageUrl);
intent.putExtra(element + "", passingContent);
v.getContext().startActivity(intent);
}
The problem is it only gives the visible views to me. Not the rest of the views. I tried auto scrolling so that the next or the previous view become visible but it doesn't seems to work. The last visible position of the child remains the same and it return a null view to me when I try to open the view just after the last visible view.
Assume there are 5 stories. Then I will see only 3 stories in the screen the rest can be seen by scrolling. When I click any of the stories. I can only navigate between 1,2 and 3. When I try to click right from story 3 to see the story 4. The current story is killed by finish() function and null is returned in the nextView variable because of which the story 4 is not loaded and I am returned to the MainActivity.
I have to navigate to all stories present in my recycler view.
Do these changes may help:
1/
I think you should use ViewPager. It automatically snaps to the item without scrollTo to index. Or keep using RecyclerView with the help of SnapHelper
2/
Modify onClickView method not to be static, and don't need View v to work. I see you just need View v just for the context. Why not just pass the context to that method. It's not proper to use a parameter like that, and that approach traps you into 3/ problem.
3/
nextView = MainActivity.linearLayoutManager.getChildAt(position);
You already know how RecyclerView works, just avoid using getChildAt because in some cases, the child you want hasn't been created yet. Base on your code, I think you don't even need to get the nextView
As told by Tam Huynh. The 1st point helped me in getting the new views in the linear layout. The views were working the fine.
There was a problem in the parameter of the function getChildAt. I have to pass the same position I was in previously. Because relatively the position(index) will not change for the child views.
index 0 -> story number 1
index 1 -> story number 2
index 2 -> story number 3
Like if there were story number 1,2 and 3 visible, the index 0 will contain 1st story, index 1 will contain 2nd and index 2 will contain 3rd story. when user clicked the right button on the 3rd story. The 4th story is first visible and now the screen have 2,3 and 4 visible. but the index of the 4th story will remain 3rd only. As now indexing will be like
index 0 -> story number 2
index 1 -> story number 3
index 2 -> story number 4
So, instead of passing position as parameter, currentPosition should be passed in getChildAt
I know how to do this for 2 images but what about 3 images.
public void fadeBardock(View view) {
ImageView bardock = (ImageView) findViewById(R.id.bardock);
ImageView goku = (ImageView) findViewById(R.id.goku);
ImageView gohan = (ImageView) findViewById(R.id.gohan);
bardock.animate().alpha(0 f).setDuration(3000);
goku.animate().alpha(0 f).setDuration(4000);
gohan.animate().alpha(1 f).setDuration(5000);
}
After clicking on button I'm directly getting the third image without getting the second image.
Try this code:
bardock.animate().alpha(0f).setDuration(3000);
goku.setAlpha(0f);
goku.animate().alpha(1f).setDuration(3000).setStartDelay(1500);
goku.animate().alpha(0f).setDuration(3000).setStartDelay(4500);
gohan.setAlpha(0f);
gohan.animate().alpha(1f).setDuration(3000).setStartDelay(6000);
You can change duration and start delays to achieve your optimal result.
On More than one imageviews,
1. Create an array of ImageView.
2. Initialize the views in it.
3. assign unique id's to each view in same loop.
[ Another thing is, you can initialize the views in one for loop in onCreate() and then on button click, apply another for loop for animation.]
Now, using an index of array, assign an animation to each view with delay from previous views.
Start animation after the loop and check.
Hope it helps.
I'm having a problem with Label and TextField placement in a gridpane in response to toggled RadioButtons.
The window will display the same options except for two different labels and text fields which depend on which RadioButton the user has selected.(See images attached).
InHouse RB Selected
Outsourced RB Selected
I added the RadioButton objects to a Toggle Group, then coded the "on actions" to add the "Machine ID" or "Company Name" fields to the GridPane as needed when one of the options is selected.
My problem is that I can only select each option once, and the display of the second option only overlaps the first instance instead of replacing it. If I try to switch back again, I get a runtime error(in Netbeans) about adding the same object twice to the grid.
Any code that I have tried that could remove the node from the display had no affect on the menu's behavior.
ArrayList<Label> typeSpecLabels = new ArrayList<Label>();
ArrayList<TextField>typeSpecFields = new ArrayList<TextField>();
typeSpecLabels.add(machineIDLabel);
typeSpecLabels.add(companyLabel);
typeSpecFields.add(machineIDField);
typeSpecFields.add(companyNameField);
inHouseBtn.setOnAction(inHouseSpecificEvent ->
{
typeSpecLabels.add(machineIDLabel);
grid1.add(typeSpecLabels.get(0),0,8,1,1);
grid1.add(typeSpecFields.get(0), 1,8,1,1);
if(outSourceBtn.isArmed() == true){
grid1.getChildren().remove(companyLabel);
grid1.getChildren().remove(companyNameField);
}
});
outSourceBtn.setOnAction(outSourceSpecificEvent ->
{
typeSpecLabels.add(companyLabel);
grid1.add(companyLabel,0,8,1,1);
grid1.add(companyNameField,1,8,1,1);
if(outSourceBtn.isArmed() == true){
grid1.getChildren().remove(machineIDLabel);
grid1.getChildren().remove(machineIDField);
}
});
I have heard that I could try using 2 or 3 different scenes(one for each state of the RadioButtons), so I may try that. But if it can be done the way I have coded it so far, I would prefer to do it that way.
I would suggest to remove all type specific labels and fields from your grid and then add ones that you need. So the code will look like following:
inHouseBtn.setOnAction(inHouseSpecificEvent ->
{
grid1.getChildren().removeAll(machineIDLabel, companyLabel, machineIDField, companyNameField);
grid1.add(machineIDLabel,0,8,1,1);
grid1.add(machineIDField, 1,8,1,1);
});
outSourceBtn.setOnAction(outSourceSpecificEvent ->
{
grid1.getChildren().removeAll(machineIDLabel, companyLabel, machineIDField, companyNameField);
grid1.add(companyLabel,0,8,1,1);
grid1.add(companyNameField,1,8,1,1);
});
This code ended up working, as Pavlo suggested.
Although I just removed the objects specific to the opposing event.
The code works with no errors or overlapping.
inHouseBtn.setOnAction(inHouseSpecificEvent ->
{
grid1.add(machineIDLabel,0,8,1,1);
grid1.add(machineIDField,1,8,1,1);
grid1.getChildren().remove(companyLabel);
grid1.getChildren().remove(companyNameField);
});
outSourceBtn.setOnAction(outSourceSpecificEvent ->
{
grid1.add(companyLabel,0,8,1,1);
grid1.add(companyNameField,1,8,1,1);
grid1.getChildren().remove(machineIDLabel);
grid1.getChildren().remove(machineIDField);
});
That title was sort of a mouthful. Basically, I have these CardViews within a RecyclerView. I have a faux animation to expand and shrink the CardViews when they're clicked. I do this by setting various elements inside them to View.GONE or View.VISIBLE depending on if the card is expanded or not.
Here is the code for expanding/collapsing the cards:
// Expand the CardView
private boolean expand(View cardView) {
// Make the shortened ("intro") text invisible and make the full text visible
mIntroTextView.setVisibility(View.GONE);
mExpandableIndicator.setVisibility(View.GONE);
mCollapseIndicator.setVisibility(View.VISIBLE);
mInfoTextView.setVisibility(View.VISIBLE);
return true;
}
// Collapse the CardView
private boolean collapse(View cardView) {
// Make the shortened ("intro") text visible and make the full text invisible
mInfoTextView.setVisibility(View.GONE);
mCollapseIndicator.setVisibility(View.GONE);
mExpandableIndicator.setVisibility(View.VISIBLE);
mIntroTextView.setVisibility(View.VISIBLE);
return false;
}
It works fine except if I tap a card while scrolling, the card will move out of place, overlapping with other cards as shown in these pictures:
https://imgur.com/a/XJ901
I can provide other code if needed.
Any ideas? Thank you!
I'm a very unexperienced programmer, so please bear with me for my lack of knowledge.
I have a program with 168 different buttons, which each count how many times they have been each pressed. After having either pressed or not pressed all of the buttons i need to inactivate and grey-out those which have not been pressed. So far I've used an 3D array to store how many times each button has been pressed, and have made a simple code:
if(a[0][0][0]<1)
{
ImageButton button_a1=(ImageButton) findViewById(R.id.button1a);
button_ca1.setEnabled(false);
button_ca1.setAlpha(6);
}
The only problem is that since each buttonID is different i have to do this 168 separated times. Is there any way to make this into a simple loop that doesn't take up over 1000 lines of code?
The program is written using Eclipse and is used for an Android app.
If all the buttons are in same layout, you can use getChildCount():
LinearLayout layout = setupLayout();
int count = layout.getChildCount();
View v = null;
for(int i=0; i<count; i++) {
v = layout.getChildAt(i);
if (v instanceof ImageButton) {
v.setEnabled(false);
v.setAlpha(6);
}
}
If not, simply create a Set, List or Array with all buttons and iterate over it:
List<ImageButton> buttons = new ArrayList<ImageButton>();
// be sure buttons is visible in the method
// when creating the buttons put them inside the list
Then in your method:
if(a[0][0][0]<1)
{
// disable all buttons
for(ImageButton button : buttons) {
button.setEnabled(false);
button.setAlpha(6);
}
}