As the title says,
When using startLabel.setVisibility(View.GONE);
The app Crashes and I am not sure how to fix
The Java code below.
public class Main extends AppCompatActivity {
private TextView scoreLabel;
private TextView startLabel;
private ImageView box;
private ImageView orange;
private ImageView pink;
private ImageView black;
// Position
private int boxY;
private int boxX;
// Initialize Class
private Handler handler = new Handler();
private Timer timer = new Timer();
//Status Check
private boolean action_flg = false;
private boolean start_flg = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scoreLabel = (TextView) findViewById(R.id.scoreLabel);
scoreLabel = (TextView) findViewById(R.id.startLabel);
box = (ImageView) findViewById(R.id.box);
orange = (ImageView) findViewById(R.id.orange);
pink = (ImageView) findViewById(R.id.pink);
black = (ImageView) findViewById(R.id.black);
//Moves images to out of the screen
//orange.setX(-80.0f);
orange.setY(-80.0f);
// pink.setX(-80.0f);
pink.setY(-80.0f);
//black.setX(-80.0f);
black.setY(-80.0f);
boxY = 200;
}
public void changePos()
{
//Move box
if (action_flg == true)
{
// touching
boxY -= 20;
} else {
//released
boxY += 20;
}
box.setY(boxY);
}
public boolean onTouchEvent(MotionEvent me)
{
if (start_flg == false)
{
start_flg = true;
//Issue here with setting the visibility of the start
// startLabel.setVisibility(View.GONE);
timer.schedule(new TimerTask()
{
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
changePos();
}
});
}
// Changing these numbers slows down how fast the box moves.
}, 0, 100);
}else {
if(me.getAction() == MotionEvent.ACTION_DOWN)
{
action_flg = true;
}else if (me.getAction() == MotionEvent.ACTION_UP){
action_flg = false;
}
}
return true;
}
}
Here is the XML version of the code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="me.scott.nathan.catchtheball.Main">
<TextView
android:id="#+id/scoreLabel"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Score : 300"
android:textSize="18sp"
android:paddingLeft="10dp"
android:gravity="center_vertical">
</TextView>
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/startLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tap to Start"
android:textSize="30sp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="130dp"
/>
<ImageView
android:id="#+id/box"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/box"
android:layout_gravity="center_vertical"
/>
<ImageView
android:id="#+id/orange"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="#drawable/orange" />
<ImageView
android:id="#+id/black"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="#drawable/black" />
<ImageView
android:id="#+id/pink"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="#drawable/pink" />
</FrameLayout>
<!--
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.22" />
-->
</LinearLayout>
Anyone help appreciated to fix this issue, Thanks
Your startLabel is null (copy paste problem?^^). Replace this:
scoreLabel = (TextView) findViewById(R.id.startLabel);
with this:
startLabel = (TextView) findViewById(R.id.startLabel);
Related
I'm developing a ChatApp with the function of Audio Messages. The Recording and playing of this Audio Messages are working very well, but if i click on Play Button the Recyclerview is scrolling up. Anyone have an idea?
Sorry for my bad english, i'm from Germany ;)
AdapterChat.Java
private static final int MSG_TYPE_LEFT = 0;
private static final int MSG_TYPE_RIGHT = 1;
Context context;
List<ModelChat> chatList;
String imageUrl;
FirebaseUser fUser;
public AdapterChat(Context context, List<ModelChat> chatList, String imageUrl) {
this.context = context;
this.chatList = chatList;
this.imageUrl = imageUrl;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
//inflate layouts: row_chat_left.xml for receiver, row_chat_right.xml for sender
if (i == MSG_TYPE_RIGHT) {
View view = LayoutInflater.from(context).inflate(R.layout.row_chat_right, viewGroup, false);
return new MyHolder(view);
}
else {
View view = LayoutInflater.from(context).inflate(R.layout.row_chat_left, viewGroup, false);
return new MyHolder(view);
}
}
public void add(ModelChat object) {
chatList.add(object);
add(object);
}
#SuppressLint("ClickableViewAccessibility")
#Override
public void onBindViewHolder(#NonNull final MyHolder myHolder, final int i) {
final String message = chatList.get(i).getMessage();
String timeStamp = chatList.get(i).getTimestamp();
String type = chatList.get(i).getType();
if (type.equals("text") || message.equals(R.string.message_was_deleted)) {
//text message
myHolder.messageTv.setVisibility(View.VISIBLE);
myHolder.messageIv.setVisibility(View.GONE);
myHolder.playAudioBtn.setVisibility(View.GONE);
myHolder.messageVoiceSb.setVisibility(View.GONE);
myHolder.sbCurrentTime.setVisibility(View.GONE);
myHolder.sbTotalDuration.setVisibility(View.GONE);
myHolder.messageTv.setText(message);
}
else if (type.equals("audio")) {
//audio message
myHolder.messageTv.setVisibility(View.GONE);
myHolder.messageIv.setVisibility(View.GONE);
myHolder.playAudioBtn.setVisibility(View.VISIBLE);
myHolder.messageVoiceSb.setVisibility(View.VISIBLE);
myHolder.sbCurrentTime.setVisibility(View.VISIBLE);
myHolder.sbTotalDuration.setVisibility(View.VISIBLE);
myHolder.voiceMessageUrl = message;
myHolder.getAdapterPosition();
myHolder.playAudioBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (myHolder.mediaPlayer.isPlaying()) {
myHolder.handler.removeCallbacks(myHolder.updater);
myHolder.mediaPlayer.pause();
myHolder.playAudioBtn.setImageResource(R.drawable.ic_play_btn);
}
else {
myHolder.mediaPlayer.start();
myHolder.playAudioBtn.setImageResource(R.drawable.ic_pause_btn);
myHolder.updateSeekbar();
}
}
});
myHolder.prepareMediaPlayer();
myHolder.messageVoiceSb.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
SeekBar seekBar = (SeekBar) view;
int playPosition = (myHolder.mediaPlayer.getDuration() / 100) * seekBar.getProgress();
myHolder.mediaPlayer.seekTo(playPosition);
myHolder.sbCurrentTime.setText(myHolder.milliSecondsToTimer(myHolder.mediaPlayer.getCurrentPosition()));
return false;
}
});
myHolder.mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
myHolder.messageVoiceSb.setSecondaryProgress(i);
}
});
myHolder.mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
myHolder.messageVoiceSb.setProgress(0);
myHolder.playAudioBtn.setImageResource(R.drawable.ic_play_btn);
myHolder.mediaPlayer.reset();
myHolder.prepareMediaPlayer();
}
});
}
else {
//image message
myHolder.messageIv.setVisibility(View.VISIBLE);
myHolder.messageTv.setVisibility(View.GONE);
myHolder.playAudioBtn.setVisibility(View.GONE);
myHolder.messageVoiceSb.setVisibility(View.GONE);
myHolder.sbCurrentTime.setVisibility(View.GONE);
myHolder.sbTotalDuration.setVisibility(View.GONE);
Picasso.get().load(message).placeholder(R.drawable.ic_image_black).into(myHolder.messageIv);
}
//set data
myHolder.messageTv.setText(message);
myHolder.timeTv.setText(timeStamp);
try {
Picasso.get().load(imageUrl).into(myHolder.profileIv);
}
catch (Exception e) {
}
myHolder.messageLayout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//show delete message confirm dialog
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.delete);
builder.setMessage("Are you sure to delete this message?");
//delete button
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
deleteMessage(i);
}
});
//cancel delete button
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//dismiss dialog
dialog.dismiss();
}
});
//create and show dialog
builder.create().show();
return false;
}
});
//set seen/delivered status of message
if (i==chatList.size()-1) {
if (chatList.get(i).isSeen()) {
myHolder.isSeenTv.setText("Seen");
}
else {
myHolder.isSeenTv.setText("Delivered");
}
}
else {
myHolder.isSeenTv.setVisibility(View.GONE);
}
}
private void deleteMessage(int position) {
final String myUID = FirebaseAuth.getInstance().getCurrentUser().getUid();
/*Logic:
* Get timeStamp of clicked message
* Compare the timeStamp of the clicked message with all messages in CHats
* Where both values matches, delete that message
* This will allow sender to delete his and receiver's message*/
String msgTimeStamp = chatList.get(position).getTimestamp();
final String type = chatList.get(position).getType();
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("Chats");
Query query = dbRef.orderByChild("timestamp").equalTo(msgTimeStamp);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()) {
/*if you want to allow sender to delete only his message then
* compare sender value with current user's uid
* if they match means its the message of sender that is trying to delete*/
if (ds.child("sender").getValue().equals(myUID)) {
if (type.equals("audio")) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("type", "text");
ds.getRef().updateChildren(hashMap);
} else if (type.equals("image")) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("type", "text");
ds.getRef().updateChildren(hashMap);
}
/*We can do one of two things here
* 1) Remove the message from chats
* 2) Set the value of message "This messages was deleted..." */
//1) Remove the message from Chats
//ds.getRef().removeValue();
//2) Set the value of message "This message was deleted..."
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("message", "This message was deleted...");
ds.getRef().updateChildren(hashMap);
Toast.makeText(context, "message deleted...", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context, "You can delete only your messages...", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public int getItemCount() {
return chatList.size();
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public int getItemViewType(int position) {
//get currently signed in user
fUser = FirebaseAuth.getInstance().getCurrentUser();
if (chatList.get(position).getSender().equals(fUser.getUid())) {
return MSG_TYPE_RIGHT;
}
else {
return MSG_TYPE_LEFT;
}
}
//view holder class
class MyHolder extends RecyclerView.ViewHolder {
//views
ImageView profileIv, messageIv;
ImageButton playAudioBtn;
SeekBar messageVoiceSb;
TextView messageTv, timeTv, isSeenTv, sbCurrentTime, sbTotalDuration;
LinearLayout messageLayout; //for click listener to show delete option
MediaPlayer mediaPlayer;
Handler handler = new Handler();
String voiceMessageUrl = null;
#SuppressLint("ClickableViewAccessibility")
public MyHolder(#NonNull View itemView) {
super(itemView);
//init views
profileIv = itemView.findViewById(R.id.profileIv);
messageIv = itemView.findViewById(R.id.messageIV);
messageTv = itemView.findViewById(R.id.messageTv);
messageVoiceSb = itemView.findViewById(R.id.messageVoiceSb);
playAudioBtn = itemView.findViewById(R.id.playAudioBtn);
sbCurrentTime = itemView.findViewById(R.id.sbCurrentTime);
sbTotalDuration = itemView.findViewById(R.id.sbTotalDuration);
timeTv = itemView.findViewById(R.id.timeTv);
isSeenTv = itemView.findViewById(R.id.isSeenTv);
messageLayout = itemView.findViewById(R.id.messageLayout);
mediaPlayer = new MediaPlayer();
messageVoiceSb.setMax(100);
}
private void prepareMediaPlayer() {
try {
mediaPlayer.setDataSource(voiceMessageUrl); //url of audio file to play
mediaPlayer.prepare();
sbTotalDuration.setText(milliSecondsToTimer(mediaPlayer.getDuration()));
} catch (Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekbar();
long currentDuration = mediaPlayer.getCurrentPosition();
sbCurrentTime.setText(milliSecondsToTimer(currentDuration));
}
};
private void updateSeekbar() {
if (mediaPlayer.isPlaying()) {
messageVoiceSb.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration()) * 100));
handler.postDelayed(updater, 1000);
}
}
private String milliSecondsToTimer(long milliSeconds) {
String timerString = "";
String secondsString;
int hours = (int) (milliSeconds / (1000 * 60 * 60));
int minutes = (int) (milliSeconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliSeconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
if (hours > 0) {
timerString = hours + ":";
}
if (seconds < 10) {
secondsString = "0" + seconds;
} else {
secondsString = "" + seconds;
}
timerString = timerString + minutes + ":" + secondsString;
return timerString;
}
}
chatActivity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/chatBackground"
tools:context=".ChatActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#color/colorPrimaryDark"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profileIv"
android:layout_width="35dp"
android:layout_height="35dp"
android:scaleType="centerCrop"
android:src="#drawable/ic_default"
app:civ_circle_background_color="#color/colorPrimaryDark"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_marginStart="20dp">
<!-- Receiver Name-->
<TextView
android:id="#+id/nameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="His Name"
android:textColor="#color/colorWhite"
android:textSize="18sp"
android:textStyle="bold" />
<!-- Receiver Status i.e online or offline-->
<TextView
android:id="#+id/userStatusTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="online"
android:textColor="#color/colorWhite"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="#+id/blockIv"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:src="#drawable/ic_unblocked_green"
android:visibility="invisible"/>
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
<!-- RecyclerView-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/chat_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar"
android:layout_above="#id/chatLayout" />
<!-- send message edit text and button in layout-->
<LinearLayout
android:id="#+id/chatLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:background="#color/textInputBackground"
android:orientation="horizontal">
<!-- ImageButton: to send Image-->
<ImageButton
android:id="#+id/attachBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#null"
android:src="#drawable/ic_attach_black" />
<!-- EditText: input message-->
<EditText
android:id="#+id/messageEt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#null"
android:inputType="textCapSentences|textMultiLine"
android:padding="15dp"
android:hint="Start typing" />
<Chronometer
android:id="#+id/record_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textSize="14sp"
android:textColor="#color/colorPrimary" />
<!-- Button: voice message-->
<ImageButton
android:id="#+id/recordBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#null"
android:src="#drawable/ic_record_btn_stopped" />
<!-- Button: send message-->
<ImageButton
android:id="#+id/sendBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#null"
android:src="#drawable/ic_send" />
</LinearLayout>
row_chat_right.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="#+id/messageLayout"
android:padding="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="end">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/profileIv"
app:civ_border_color="#null"
android:visibility="gone"
android:src="#drawable/ic_default_img" />
<TextView
android:id="#+id/messageTv"
android:layout_weight="1"
android:textSize="16sp"
android:textColor="#color/textColor"
android:background="#drawable/bg_sender"
android:padding="15dp"
android:text="His Message"
android:visibility="gone"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/messageIV"
android:layout_width="200dp"
android:layout_height="200dp"
android:adjustViewBounds="true"
android:padding="15dp"
android:src="#drawable/ic_image_black"
android:scaleType="fitCenter"
android:background="#drawable/bg_sender" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/bg_sender"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/playAudioBtn"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:background="#null"
android:src="#drawable/ic_play_btn" />
<SeekBar
android:id="#+id/messageVoiceSb"
android:visibility="gone"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/playAudioBtn"
android:padding="10dp"
android:layout_marginTop="10dp"
android:max="100"
android:progress="0" />
<TextView
android:id="#+id/sbCurrentTime"
android:visibility="gone"
android:text="0:00"
android:textStyle="bold"
android:textSize="12sp"
android:layout_marginStart="2dp"
android:layout_below="#id/messageVoiceSb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/sbTotalDuration"
android:visibility="gone"
android:textStyle="bold"
android:text="0:10"
android:textSize="12sp"
android:layout_below="#id/messageVoiceSb"
android:layout_toEndOf="#id/messageVoiceSb"
android:layout_marginEnd="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
<TextView
android:id="#+id/timeTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textAlignment="textEnd"
android:text="07/08/2020 23:00PM"
android:textColor="#color/textColor"
android:textSize="12sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/isSeenTv"
android:gravity="end"
android:textAlignment="textEnd"
android:text="delivered" />
Here is the Fix!!
<TextView
android:layout_width="match_parent" <-- This is what I changed
android:layout_height="wrap_content"/>
<SeekBar
android:layout_width="match_parent" <-- Check this as well
android:layout_height="wrap_content"/>
I have a TextView with an arrow set on the right of it. I want the arrow to rotate when it is clicked and return it back to the previous position when it is clicked again to show and hide text. I have been able to show and hide the information I just can't get the rotation animation to work.
XML
<TextView
android:id="#+id/expandable_first_next_last_air_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="8dp"
android:drawableEnd="#drawable/ic_keyboard_arrow_down_white_24dp"
android:drawableTint="?attr/textColor"
android:text="First, Next & Last Air Date"
android:textColor="?attr/textColor"
android:textSize="26sp" />
TextView OnClick Listener
tvExpandableFirstNextLastAirDate = findViewById(R.id.expandable_first_next_last_air_date);
tvExpandableFirstNextLastAirDate.setOnClickListener(v -> {
if (isTextViewClicked){
tvFirstNextLastAirDate.setMaxLines(0);
isTextViewClicked = false;
}
else{
tvFirstNextLastAirDate.setMaxLines(Integer.MAX_VALUE);
isTextViewClicked = true;
}
});
java:
final TextView textView = findViewById(R.id.text_view);
final ImageView imageView = findViewById(R.id.image_view);
final TextView textView2 = findViewById(R.id.text_view2);
final ImageView imageView2 = findViewById(R.id.image_view2);
final AnimationSet animSetUp = new AnimationSet(true);
animSetUp.setInterpolator(new DecelerateInterpolator());
animSetUp.setFillAfter(true);
animSetUp.setFillEnabled(true);
final AnimationSet animSetDown = new AnimationSet(true);
animSetDown.setInterpolator(new DecelerateInterpolator());
animSetDown.setFillAfter(true);
animSetDown.setFillEnabled(true);
final RotateAnimation animRotateUp = new RotateAnimation(0.0f, 180.0f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animRotateUp.setDuration(1500);
animRotateUp.setFillAfter(true);
animSetUp.addAnimation(animRotateUp);
final RotateAnimation animRotateDown = new RotateAnimation(180.0f, 0.0f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animRotateDown.setDuration(1500);
animRotateDown.setFillAfter(true);
animSetDown.addAnimation(animRotateDown);
final boolean[] isTextViewClickedForTextView1 = {true};
final boolean[] isTextViewClickedForTextView2 = {true};
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isTextViewClickedForTextView1[0]) {
textView.setMaxLines(0);
isTextViewClickedForTextView1[0] = false;
imageView.startAnimation(animSetUp);
} else {
imageView.startAnimation(animSetDown);
textView.setMaxLines(Integer.MAX_VALUE);
isTextViewClickedForTextView1[0] = true;
}
}
});
textView2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isTextViewClickedForTextView2[0]) {
textView2.setMaxLines(0);
isTextViewClickedForTextView2[0] = false;
imageView2.startAnimation(animSetUp);
} else {
imageView2.startAnimation(animSetDown);
textView2.setMaxLines(Integer.MAX_VALUE);
isTextViewClickedForTextView2[0] = true;
}
}
});
XML :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_margin="10dp"
android:padding="10dp"
android:text="text view 1"
android:textAlignment="viewStart"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:padding="5dp"
android:src="#drawable/ic_baseline_arrow_drop_down_24"
app:layout_constraintBottom_toBottomOf="#+id/text_view"
app:layout_constraintEnd_toEndOf="#+id/text_view"
app:layout_constraintTop_toTopOf="#+id/text_view" />
<TextView
android:id="#+id/text_view2"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_margin="10dp"
android:padding="10dp"
android:text="text view 2"
android:textAlignment="viewStart"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_view"/>
<ImageView
android:id="#+id/image_view2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:padding="5dp"
android:src="#drawable/ic_baseline_arrow_drop_down_24"
app:layout_constraintBottom_toBottomOf="#+id/text_view2"
app:layout_constraintEnd_toEndOf="#+id/text_view2"
app:layout_constraintTop_toTopOf="#+id/text_view2" />
</androidx.constraintlayout.widget.ConstraintLayout>
res/anim/ic_baseline_arrow_drop_down_24.xml :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="#android:anim/cycle_interpolator">
<rotate android:fromDegrees="0"
android:toDegrees="180"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000" />
</set>
first of all, I'll explain the expected behavior of the App.
What does the App do?
When I run the App I see this view:
Now if you hit the "+" button you'll see this Dialog:
By clicking Add this entry will be added to a ListView. I added two items. This looks like this:
Expected Result
Now when I touch and hold the mic icon of the list items it should start recording audio through the device microphone and then save this recording with the name of the bold entry, that means e.g. the first recording will get the name A.3gp, the second one B.3gp and so on..
Actual Result (UPDATE 07.12.2017)
The current state is:
Every item in the list gets his "own" recording. That means if I touch and hold the microphone icon of the first item in the list, it is doing what it should do. The same goes for all other items on the list.
When I add the first item A, then touch its record icon, a file will be created with the name A.3gp (which is correct behavior).
When I add the second item B then do nothing and then add a third item C and touch the record icon for B, a file will be created with the name C.3gp (which is not a correct behavior, it should be B.3gp).
Now to the fun part.
Code (UPDATE 07.12.2017)
1. The Model
public class Word {
private String mForeignTranslation;
private String mDefaultTranslation;
private ImageView mRecordIconImageResourceId;
private MediaRecorder mMediaRecorder;
public Word(String foreignTranslation, String defaultTranslation, ImageView recordIconImageResourceId) {
this.mForeignTranslation = foreignTranslation;
this.mDefaultTranslation = defaultTranslation;
this.mRecordIconImageResourceId = recordIconImageResourceId;
}
public Word(String foreignTranslation, String defaultTranslation) {
this.mForeignTranslation = foreignTranslation;
this.mDefaultTranslation = defaultTranslation;
}
public String getDefaultTranslation() {
return mDefaultTranslation;
}
public String getForeignTranslation() {
return mForeignTranslation;
}
public ImageView getRecordIconImageResourceId() {
return mRecordIconImageResourceId;
}
public MediaRecorder getMediaRecorder() {
return mMediaRecorder;
}
public void setDefaultTranslation(String mDefaultTranslation) {
this.mDefaultTranslation = mDefaultTranslation;
}
public void setForeignTranslation(String mForeignTranslation) {
this.mForeignTranslation = mForeignTranslation;
}
public void setRecordIconImageResourceId(ImageView recordIconImageResourceId) {
this.mRecordIconImageResourceId = recordIconImageResourceId;
}
public void setMediaRecorder(MediaRecorder mMediaRecorder) {
this.mMediaRecorder = mMediaRecorder;
}
}
2. The Adapter
public class WordAdapter extends ArrayAdapter<Word> {
private ArrayList<Word> wordsArrayList = new ArrayList<>();
private MediaRecorder mediaRecorder = new MediaRecorder();
public WordAdapter(#NonNull Context context, ArrayList<Word> words) {
super(context, 0, words);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.my_word_list_items,parent,false);
}
Word currentWord = getItem(position);
TextView foreignWord = listItemView.findViewById(R.id.myForeignWord);
foreignWord.setText(currentWord.getForeignTranslation());
TextView defaultWord = listItemView.findViewById(R.id.myDefaultWord);
defaultWord.setText(currentWord.getDefaultTranslation());
final ImageView recordIconImageView = listItemView.findViewById(R.id.recordIconImageView);
wordsArrayList = MyWordsActivity.getWordsArrayList();
recordIconImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN: {
recordIconImageView.setImageResource(R.drawable.mic_red);
startAudioRecording();
break;
}
case MotionEvent.ACTION_UP: {
recordIconImageView.setImageResource(R.drawable.mic_black);
stopAudioRecording();
break;
}
}
return true;
}
});
return listItemView;
}
private ArrayList<Word> getWordsArrayList() {
return wordsArrayList;
}
private void startAudioRecording() {
if (wordsArrayList != null) {
Log.i("ArrayListe", wordsArrayList.toArray().toString());
getMediaRecorderReady();
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
Toast.makeText(this.getContext(), "Recording started", Toast.LENGTH_SHORT).show();
}
}
private void stopAudioRecording() {
try {
mediaRecorder.stop();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(this.getContext(), "Recording stopped", Toast.LENGTH_SHORT).show();
}
private void getMediaRecorderReady() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+"speakmylanguage"+"/"+MyWordsActivity.getForeignWord()+".3gp");
}
}
3. The Activity
public class MyWordsActivity extends AppCompatActivity {
private static String defaultWord, foreignWord;
private static ArrayList<Word> wordsArrayList = new ArrayList<>();
WordAdapter wordAdapter;
// Main Activity Views
TextView hintTextView;
ListView myWordsListView;
FloatingActionButton floatingButtonAddNewWord;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_words);
// Init Main Activity Views
hintTextView = findViewById(R.id.hintTextView);
myWordsListView = findViewById(R.id.myWordsList);
floatingButtonAddNewWord = findViewById(R.id.fabAddNewWord);
floatingButtonAddNewWord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final Dialog addNewWordsDialog = new Dialog(MyWordsActivity.this);
addNewWordsDialog.setContentView(R.layout.activity_add_new_words);
final EditText addForeignWordEditText = addNewWordsDialog.findViewById(R.id.addForeignWordEditText);
final EditText addDefaultWordEditText = addNewWordsDialog.findViewById(R.id.addDefaultWordEditText);
final Button addNewWordButton = addNewWordsDialog.findViewById(R.id.addNewWordButton);
addNewWordsDialog.show();
addNewWordButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!addDefaultWordEditText.getText().toString().equals("") &&
!addForeignWordEditText.getText().toString().equals("")) {
foreignWord = addForeignWordEditText.getText().toString();
defaultWord = addDefaultWordEditText.getText().toString();
wordsArrayList.add(new Word(foreignWord, defaultWord));
hintTextView.setVisibility(View.GONE);
addNewWordsDialog.dismiss();
} else {
Toast.makeText(MyWordsActivity.this, "Please enter two words", Toast.LENGTH_SHORT).show();
}
}
});
wordAdapter = new WordAdapter(MyWordsActivity.this, getWordsArrayList());
myWordsListView.setAdapter(wordAdapter);
}
});
}
public static String getDefaultWord() {
return defaultWord;
}
public static void setDefaultWord(String defaultWord) {
MyWordsActivity.defaultWord = defaultWord;
}
public static String getForeignWord() {
return foreignWord;
}
public static void setForeignWord(String foreignWord) {
MyWordsActivity.foreignWord = foreignWord;
}
public static ArrayList<Word> getWordsArrayList() {
return wordsArrayList;
}
}
4. The Layouts
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myRelativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/myWordsListItems"
android:layout_width="match_parent"
android:layout_height="88dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginStart="16dp"
android:orientation="vertical">
<TextView
android:id="#+id/myForeignWord"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="bottom"
android:textAppearance="?android:textAppearanceMedium"
android:textSize="24sp"
android:textStyle="bold"
tools:text="foreign word" />
<TextView
android:id="#+id/myDefaultWord"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="top"
android:textAppearance="?android:textAppearanceMedium"
android:textSize="24sp"
tools:text="default word" />
</LinearLayout>
<ImageView
android:id="#+id/playIconImageView"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:clickable="true"
android:src="#drawable/play_icon" />
<ImageView
android:id="#+id/recordIconImageView"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="72dp"
android:clickable="true"
android:src="#drawable/mic_black" />
</RelativeLayout>
activity_my_words.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.yousef.mustafa.speakmylanguage.View.MyWordsActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:title="#string/app_name"
app:titleTextColor="#color/colorWhite" />
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myWordsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar"
android:drawSelectorOnTop="true"
android:orientation="vertical"
tools:context=".View.MyWordsActivity" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fabAddNewWord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="bottom|center"
android:layout_marginBottom="32dp"
android:tint="#color/colorWhite"
app:backgroundTint="#color/colorGrey"
app:srcCompat="#drawable/icon_add" />
<TextView
android:id="#+id/hintTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="155dp"
android:gravity="center"
android:text="#string/hint"
android:textSize="24sp"
android:textStyle="bold" />
</RelativeLayout>
activity_add_new_words.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorDialogBackground">
<LinearLayout
android:id="#+id/addNewWordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="8dp"
android:layout_marginTop="12dp"
android:text="#string/add_word_title"
android:textColor="#color/colorBlack"
android:textSize="24sp"
android:textStyle="bold" />
<EditText
android:id="#+id/addForeignWordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="4dp"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:layout_weight="5"
android:gravity="center_horizontal"
android:hint="#string/enter_foreign_word"
android:inputType="textPersonName|textCapWords"
android:textSize="24sp" />
<EditText
android:id="#+id/addDefaultWordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:layout_marginTop="4dp"
android:layout_weight="5"
android:gravity="center_horizontal"
android:hint="#string/enter_default_word"
android:inputType="textPersonName|textCapWords"
android:textSize="24sp" />
<Button
android:id="#+id/addNewWordButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="#string/button_add"
android:textAllCaps="false"
android:textSize="18sp" />
</LinearLayout>
</RelativeLayout>
I would appreciate any help. Thanks in advance.
In the startAudioRecording() method of the Activity, you set the output filename from the foreignWord field. The problem is that the foreignWord field is set to the most recently added foreign word each time the user submits a word pair in the Add Word dialog. Thus each time the user starts a recording, the name of the output file will be set to the last foreign word added.
Instead of using fields for recordingImageView, foreignWord, defaultWord, foreignWord, audioSavePath, and mediaRecorder, you should make them local variables, and pass them as parameters to your record(), startAudioRecording(), stopAudioRecording() methods with the following steps:
Just delete those fields from the beginning of the class so that you see some compilation errors where the fields were used.
Where you see an undefined variable on the left side of an assignment, make the variable local (Ctrl+V in Android Studio).
Where you see an undefined variable elsewhere, make the variable a parameter of the method (Ctrl+P).
It should work after those changes.
`
Kindly move this snippet :
recordingImageView.setOnTouchListener(new View.OnTouchListener()
{
#Override public boolean onTouch(View view, MotionEvent motionEvent)
{
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
{ recordingImageView.setImageResource(g startAudioRecording(position);
break;
}
case MotionEvent.ACTION_UP:
{
recordingImageView.setImageResource(R.drawable.mic_black);
stopAudioRecording();
break;
}
}
return true;
}
});
In Adapter , getView(...) Below accessing recordImageView.
And put startAudioRecording() , stopAudioRecording() in same adapter or all relevant method for recording is to be in Adapter.
So by this you will get click on in each individual image view. Previously when you are fetching it will only take instance of any one image view.
Now update code on "startAudioRecording()" as:
private void startAudioRecording()
{
if (checkPermission())
{
if (wordsArrayList != null)
{
audioSavePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + wordsArrayList.get(position) + ".3gp";
getMediaRecorderReady();
}
}
}
Now your second point, saving its name by any name. Will cover by above code.
Thanks and happy coding
I am working on an application which needs to save and restore the textview scroll position when the user changes the screen orientation and when the user quits the application, i am using multiple textViews(8-10) due to very very long text block. I took help from some answers here but they don't seem to work, and plz suggest a better way to include very very large text blocks in an activity. Code given below:
Thanks in advance,
chapter1.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollChapter1">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/Chapter1"
android:textSize="17sp"
android:padding="10px"
android:id="#+id/txtChapter1Title"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentA"
android:id="#+id/txtChapter1A"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1Title"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentB"
android:id="#+id/txtChapter1B"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1A"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentC"
android:id="#+id/txtChapter1C"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1B"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentD"
android:id="#+id/txtChapter1D"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1C"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentE"
android:id="#+id/txtChapter1E"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1D"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentF"
android:id="#+id/txtChapter1F"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1E"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dip"
android:width="0dip"
android:textSize="16sp"
android:padding="10px"
android:text="#string/Chapter1ContentG"
android:id="#+id/txtChapter1G"
android:maxLength="9000"
android:layout_below="#+id/txtChapter1F"
/>
</RelativeLayout>
</ScrollView>
chapter1.java:
public class chapter1 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.chapter1);
WindowManager w = getWindowManager();
Display d = w.getDefaultDisplay();
if(d.getWidth() > d.getHeight()){
Log.d("Orientation", "Landscape");
}else{
Log.d("Orientation", "Potrait");
}
}
#Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollChapter1);
final RelativeLayout relativeLayout = (RelativeLayout) scrollView.getChildAt(0);
final TextView textView = (TextView) relativeLayout.getChildAt(0);
final int firstVisibleLineOffset = textView.getLayout().getLineForVertical(scrollView.getScrollY());
final int firstVisibleCharacterOffset = textView.getLayout().getLineStart(firstVisibleLineOffset);
outState.putInt("ScrollViewContainerTextViewFirstVisibleCharacterOffset", firstVisibleCharacterOffset);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
final int firstVisibleCharacterOffset = savedInstanceState.getInt("ScrollViewContainerTextViewFirstVisibleCharacterOffset");
final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollChapter1);
scrollView.post(new Runnable() {
#Override
public void run() {
final RelativeLayout relativeLayout = (RelativeLayout) scrollView.getChildAt(0);
final TextView textView = (TextView) relativeLayout.getChildAt(0);
final int firstVisibleLineOffset = textView.getLayout().getLineStart(firstVisibleCharacterOffset);
final int pixelOffset = textView.getLayout().getLineTop(firstVisibleLineOffset);
scrollView.scrollTo(0, pixelOffset);
}
});
}
}
You need to save the state of the component in order to restore it after rotation...
Try this :
// two static variable,
public static int scrollX = 0;
public static int scrollY = -1;
//update & save their value on onPause & onResume.
#Override
protected void onPause()
{
super.onPause();
scrollX = scrollView.getScrollX();
scrollY = scrollView.getScrollY();
}
#Override
protected void onResume() {
Util.Log("X:" + scrollX + " Y:" + scrollY);
super.onResume();
//this is important. scrollTo doesn't work in main thread.
scrollView.post(new Runnable(){
#Override
public void run()
{
scrollView.scrollTo(scrollX, scrollY);
}
});
}
For screen rotation :
//save value on onSaveInstanceState
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putIntArray("SCROLL_POSITION",
new int[]{ mScrollView.getScrollX(), mScrollView.getScrollY()});
}
//Restore them on onRestoreInstanceState
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
final int[] position = savedInstanceState.getIntArray("SCROLL_POSITION");
if(position != null)
mScrollView.post(new Runnable() {
public void run() {
mScrollView.scrollTo(position[0], position[1]);
}
});
}
Hii i made a simple layout in which i use 3 image views and i make the center one movable.
Her is my layout class main.xml:-
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<view class="com.example.screenlock.MainActivity$IV"
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|fill_horizontal"
android:background="#60000000"
android:orientation="horizontal"
android:padding="7dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:scaleType="fitXY"
android:layout_alignParentLeft="true"
android:src="#drawable/browser1" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/circle" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|fill_vertical"
android:layout_weight="0"
android:scaleType="fitXY"
android:src="#drawable/lock" />
</LinearLayout>
</FrameLayout>
and My MainActivity.java class is as follows:-
public class MainActivity extends Activity {
private ImageView imageView1, imageView2;
public static class IV extends ImageView {
private MainActivity mActivity;
public IV(Context context) {
super(context);
}
public IV(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setActivity(MainActivity act) {
mActivity = act;
}
public void onSystemUiVisibilityChanged(int visibility) {
mActivity.getState().onSystemUiVisibilityChanged(visibility);
}
}
private interface State {
void apply();
State next();
void onSystemUiVisibilityChanged(int visibility);
}
State getState() {
return mState;
}
static int TOAST_LENGTH = 500;
IV mImage;
TextView mText1, mText2;
State mState;
public MainActivity() {
// TODO Auto-generated constructor stub
}
#Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
startService(new Intent(this, MyLockService.class));
System.out.println(R.id.image);
imageView2 = (ImageView)findViewById(R.id.imageView2);
imageView2.setOnTouchListener(new OnTouchListener()
{
float lastX;
PointF DownPT = new PointF(); // Record Mouse Position When Pressed Down
PointF StartPT = new PointF(); // Record Start Position of 'img'
#SuppressLint("NewApi")
#Override
public boolean onTouch(View v, MotionEvent event)
{
int eid = event.getAction();
switch (eid)
{
case MotionEvent.ACTION_MOVE :
PointF mv = new PointF( event.getX() - DownPT.x, event.getY() - DownPT.y);
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD){
v.scrollBy((int) (event.getX()-lastX), 0);
lastX = event.getX();
if(lastX >= 170){
MarginLayoutParams lp = (MarginLayoutParams) imageView2.getLayoutParams();
lp.setMargins(178, 0, 0, 0);
imageView2.setLayoutParams(lp);
}
if(lastX <= 25){
MarginLayoutParams lp = (MarginLayoutParams) imageView2.getLayoutParams();
lp.setMargins(0, -16, 0, 0);
imageView2.setLayoutParams(lp);
}
System.out.println("XXXXXXX "+lastX);
}
else{
imageView2.setX((int)(StartPT.x+mv.x));
imageView2.setY((int)(StartPT.y+mv.y));
StartPT = new PointF( imageView2.getX(), imageView2.getY() );
//System.out.println("X: "+imageView2.getX()+"Y: "+imageView2.getY());
if(imageView2.getX() < -70)
{
imageView2.setX(-103);
imageView2.setY(6);
//System.out.println("--------------------------------------");
}
else if(imageView2.getX() > 260)
{
imageView2.setX(270);
imageView2.setY(8);
finish();
}
}
break;
case MotionEvent.ACTION_DOWN :
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD){
lastX = event.getX();
}
else{
DownPT.x = event.getX();
DownPT.y = event.getY();
StartPT = new PointF( imageView2.getX(), imageView2.getY() );
}
break;
case MotionEvent.ACTION_UP :
v.scrollTo(0, 0);
break;
default :
break;
}
return true;
}
});
}
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// Use onWindowFocusChanged to get the placement of
// the image because we have to wait until the image
// has actually been placed on the screen before we
// get the coordinates. That makes it impossible to
// do in onCreate, that would just give us (0, 0).
imageView1 = (ImageView) findViewById(R.id.imageView1);
int[] a = new int[2];
imageView1.getLocationInWindow(a);
int x = a[0];
int y = a[1];
System.out.println("X "+x+" Y "+y);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I am executing this code on pre-honeycomb emulator. But when i move the center image it gets hides behind the left and right images respectively.
I want center image to shown on the rest of two images and also want to show that two images also.
Basically, the center image is a circle and rest two images are browser and lock images and i want that circle to overlaps that images.
I am working on a lock screen.
Please help in my layout problem and how i can solve this problem?????
You can try changing your layout as follows...
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<view
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.screenlock.MainActivity$IV"
android:scaleType="center" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|fill_horizontal" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#60000000"
android:orientation="horizontal"
android:padding="7dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher" />
<View
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|fill_vertical"
android:layout_weight="0"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher" />
</LinearLayout>
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_launcher" />
</FrameLayout>
</FrameLayout>