As you have discovered, the changed ECHO state is not recognized by the parser until it reaches a statement that is after the code block that contains the ECHO ON/OFF.
But there is one exception - the commands after FOR ... DO do take on the state change within the same block :-)
Note that you only need @ to suppress command output when ECHO is currently ON. If it is OFF, then there is no need for @ECHO ON. And if you turn it ON and OFF within the same code block, then you don't need it there either.
Here is a demo that echos the even test lines:
@echo off
echo Test #1
(
  echo on
  for %%. in (.) do echo Test #2
  echo off
  echo Test #3
  echo on
  for %%. in (.) do echo Test #4
  echo off
  echo Test #5
)
echo on
echo Test #6
@echo off
echo Test #7
-- OUTPUT --
Test #1
C:\test>echo Test #2
Test #2
Test #3
C:\test>echo Test #4
Test #4
Test #5
C:\test>echo Test #6
Test #6
Test #7
You might find it convenient to declare a simple echo_on "macro". The following produces the exact same output:
@echo off
setlocal
set "echo_on=echo on&for %%. in (.) do"
echo Test #1
(
  %echo_on% echo Test #2
  echo off
  echo Test #3
  %echo_on% echo Test #4
  echo off
  echo Test #5
)
echo on
echo Test #6
@echo off
echo Test #7